Как получить все сборки в решении в .NET? - PullRequest
0 голосов
/ 13 мая 2018

У меня типичное 3-уровневое .NET-приложение.

Уровень домена не ссылается на другие проекты.

Уровень доступа к данным ссылается на уровень домена и реализует некоторые репозитории.

Уровень веб-просмотра использует службы уровня домена и управляет Autofac (контейнер IOC).

Уровни доступа к домену и данным реализуют модули Autofac. Это означает, что из уровня веб-просмотра я могу сканировать все сборки и регистрировать их в Autofac, чтобы обеспечить внедрение зависимостей.

Я не хочу, чтобы мой Web View Layer знал или заботился о том, какой уровень доступа к данным используется, поэтому я не хочу включать ссылку на него. Однако, если я не ссылаюсь на уровень доступа к данным, сканирование, чтобы найти сборки, не обнаружит его.

Вот метод запуска, который вызывается на уровне веб-представления:

private static void RegisterAutofacAssemblyModules(ContainerBuilder builder)
    {
        IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.Contains("Boutique"));

        if (HostingEnvironment.InClientBuildManager)
        {
            assemblies = assemblies.Union(BuildManager.GetReferencedAssemblies().Cast<Assembly>()).Distinct();
        }

        builder.RegisterAssemblyModules(assemblies.ToArray());
    }

Я добавил .Where (), чтобы надеяться улучшить производительность, так как нужно будет сканировать меньше сборок. (Не уверен, правда это или нет).

И этот код прекрасно работает, если я ссылаюсь на уровень доступа к данным (на уровне веб-представления). Но я не хочу, чтобы уровень веб-представления ссылался на уровень доступа к данным. Итак, как я могу отсканировать сборку, чтобы убедиться, что уровень доступа к данным включен? Я хотел бы просто получить все сборки в решении, если это возможно.

1 Ответ

0 голосов
/ 14 мая 2018

Мне кажется, что вам может не хватить слоя Cross Cutting для обработки ваших регистраций контейнера IoC.

Создайте новый проект класса с именем CrossCutting.IoC и переместите в него все регистрации Autofac, кромеРегистрации уровня веб-просмотра будут обрабатываться самим веб-уровнем.

Таким образом, веб-уровень будет иметь ссылку на уровень IoC и больше не будет нуждаться в ссылке на уровень данных.Слой IoC будет иметь ссылку на любой другой проект.

Я использую SimpleInjector, поэтому я никогда не реализовывал это в Autofac, но после быстрого поиска кажется, что вам нужно использовать Модули в качествеобъяснил в этом ответ .Если вы последуете совету этого ответа и создадите по одному модулю для каждого слоя, вы можете использовать RegisterAssemblyModules и зарегистрировать все модули одновременно.

Редактировать

Я только что проверил это в проекте WebAPI с теми же слоями, что и вы, плюс CrossCutting.IoC, и это сработало.Согласно документам , вам даже не нужно использовать AppDomain, просто BuildManager:

protected void Application_Start()
{
    var builder = new ContainerBuilder();

    var config = GlobalConfiguration.Configuration;

    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    builder.RegisterWebApiFilterProvider(config);
    builder.RegisterWebApiModelBinderProvider();

    // Automatically scan and register all modules found in referenced assemblies
    var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
    builder.RegisterAssemblyModules(assemblies);

    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}

Я бы не настроил его для сканирования во время выполнения, явоспринимать это как риск, я предпочитаю говорить об этом прямо, поэтому, если хотите, просто замените часть автоматического сканирования на RegisterModule вызовов для каждого модуля:

builder.RegisterModule<CrossCuttingModule>();
builder.RegisterModule<DomainModule>();
// etc...
...