【问题标题】:How to get all assemblies in solution in .NET?如何在 .NET 中获取解决方案中的所有程序集?
【发布时间】:2018-05-13 20:37:42
【问题描述】:

我有一个典型的 3 层 .NET 应用程序。

领域层不引用其他项目。

数据访问层引用域层并实现一些存储库。

Web 视图层使用域层的服务并控制 Autofac(IOC 容器)。

域和数据访问层实现 Autofac 模块。这意味着从 Web 视图层,我可以扫描所有程序集并将它们注册到 Autofac 以提供依赖注入。

我不想让我的 Web 视图层知道或关心使用了哪个数据访问层,所以我不想包含对它的引用。但是,如果我不引用数据访问层,则查找程序集的扫描将不会拾取它。

下面是在 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() 以希望提高性能,因为需要扫描的程序集更少。 (不确定这是不是真的)。​​

如果我引用数据访问层(在 Web 视图层中),这段代码可以正常工作。但我不希望 Web 视图层引用数据访问层。那么如何扫描程序集以确保包含数据访问层?如果可能的话,我想获取解决方案中的所有程序集。

【问题讨论】:

    标签: .net .net-assembly layer n-tier-architecture


    【解决方案1】:

    在我看来,您可能缺少一个横切层来处理您的 IoC 容器注册。

    创建一个名为CrossCutting.IoC 的新类项目并将所有Autofac 注册移至其中,除了Web View Layer 注册,这些将由Web 层自己处理。

    因此,Web 层将具有对 IoC 层的引用,并且不再需要对数据层的引用。 IoC 层将引用其他所有项目。

    我使用 SimpleInjector,所以我从来没有在 Autofac 中实现过这个,但是在快速搜索之后,看起来你需要使用 Modules,正如 answer 中所解释的那样。如果您遵循该答案的建议并为每一层创建一个模块,那么您可以使用RegisterAssemblyModules 并一次注册所有模块。

    编辑

    我刚刚在一个与您具有相同层的 WebAPI 项目中对此进行了测试,再加上CrossCutting.IoC 并且它有效。根据the docs,您甚至不必使用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...
    

    【讨论】:

    • 这实际上是一个相当不错的主意。所以 IOC 层将引用数据访问和域,它会严格包含一些帮助类来注册必要的项目。 Web 视图(和单元测试)依次引用 IOC 层以注册所需的所有依赖项。这将不允许对数据访问逻辑/类(甚至如果我添加了 API 层,甚至是域)的不当使用,并且如果我要交换/添加层也允许灵活性。我也已经让 Autofac 模块工作了。我会做更多的研究并在项目中尝试一下。谢谢!!!
    • 好的,所以我重构了 IOC 层,只是为了将程序集注册到 Autofac。 IOC 层引用域和数据访问层,因此它可以注册程序集。 Web 视图仅引用域和 IOC 层。但是,除非我在 Web 视图层中包含引用,否则 IOC 层中的 AppDomain.CurrentDomain.GetAssemblies() 不会拉数据访问程序集??
    • 我已经编辑了答案,看看。希望对你有帮助,干杯。
    • 哇,这太有道理了!非常感谢您花时间提供帮助!我将在项目中对其进行测试:)
    猜你喜欢
    • 1970-01-01
    • 2011-03-29
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多