【问题标题】:MEF & correct decoupling of a N layered Domain Driven Design architectureMEF 和 N 层域驱动设计架构的正确解耦
【发布时间】:2016-08-23 08:53:18
【问题描述】:

我一直在阅读 Microsoft 的 NLayered Domain Driven Design Architecture 指南,我想将 MEF 实现为我的 DI 容器。

我想通过创建 3 个项目来测试 MEF:只有接口的 ContractProject。 ImplementationProject 具有使用 Export[typeof(Interface)] 注释实现此接口的类。还有一个控制台应用程序来测试它。

根据依赖注入原则,高层不应该引用低层,反之亦然。它们都应该引用一个抽象层(接口)。

我尝试应用它。控制台应用程序引用 ContractsProject, implementationProject 引用 ContractsProject。但是如果程序集中没有 ImplentationProject dll,MEF 找不到 EXPORT 类。我看过一个教程,他们手动将 dll 添加到 MainApp 的 bin 文件夹中。好消息是您不能通过动态避免“添加引用”来直接访问实现方法,但我认为这不是正确的做法,因为每次更改时我都必须手动添加 dll。使用 NLayered Domain Driven Design 架构应用程序时,我需要大量的 dll。

这是否意味着 MEF 不是依赖注入所需的正确工具? (本书使用Unity)

代码如下:

namespace Contracts
{
    public interface ISampleContract
    {
        string DoSomething();
    }
}

namespace Implementation
{
    [Export(typeof(ISampleContract))]
    public class Sample : ISampleContract
    {
        public string DoSomething()
        {
            return "I did something ";
        }
    }
}

程序:

namespace Console
{
    class Program
    {
        [Import]
        public ISampleContract sample { get; set; }

        static void Main(string[] args)
        {
            Program p = new Program();
            p.Run();
        }

        public void Run()
        {
            var catalog = new AggregateCatalog(
            new AssemblyCatalog(Assembly.GetExecutingAssembly()),
            new DirectoryCatalog("."));
            var container = new CompositionContainer(catalog);

            container.ComposeParts(this);
            Console.WriteLine(sample.DoSomething());
            Console.ReadKey();
        }
    }
}

如果我没有在主程序中引用实现 dll,ComposeParts() 事情会失败,因为它找不到与约束匹配的导出...有没有办法在不引用 dll 的情况下解决这个问题或应该我完全选择另一个 DI 工具?比如 Unity?

编辑 如果我在实施项目上配置构建后事件以将其 dll 复制到我的控制台 bin,它会起作用。我不确定这是否是一个好的解决方案?

copy /Y "$(TargetFileName)" "$(SolutionDir)Console\bin\Debug\$(ProjectName).dll" 

【问题讨论】:

  • 顺便说一句,我不确定 MEF 是否是控制容器反转的最佳选择...
  • 我才刚刚开始意识到这一点。似乎 MEF 还没有提供 DI 容器的全部功能。

标签: .net dependency-injection domain-driven-design inversion-of-control mef


【解决方案1】:

您应该确保 Visual Studio 确实在构建 Implementation.dll。通常如果你只构建 Console.dll 会发生什么 Console.dll 并且它的依赖项是构建的。任何 DI 框架都会有这个问题。

解决此问题的一种方法是转到解决方案 -> 属性 -> 项目依赖项并在那里标记构建依赖项。 (请注意,dll 将位于它们自己的项目 bin 目录中,您可以在构建后的步骤中将它们全部部署到插件目录中)

在稍后阶段,您可能会或可能不会设置一些更高级的工具来独立构建和部署您的 implementation.dll(我只会在合理的大型项目或具有特定插件要求的项目中这样做)

编辑:unity(和其他一些)的缺点是它经常演变为创建一个巨大的映射文件(迫使您同时拥有构建和代码依赖)。

【讨论】:

  • 标记了构建依赖项,但它仍然不能解决我的问题。 MEF 找不到导出标记类。所有 dll 都在他们自己的项目 bin 中,但如果控制台 bin 文件夹中不存在 Implementation.dll,MEF 仍然找不到 Implementation.dll。调试目录,加载的文件只包含Contract.dll文件
  • 如果我将 Implementation.dll 的构建输出配置为控制台的 bin 文件夹,它就可以工作。这是一个好的解决方案吗?
  • 我会将所有其他项目输出到“插件”目录中,然后将 DirectoryCatalog 的路径指向该目录。 (更容易看到什么是分开的,什么不是)我经常看到这通常是通过使用 xcopy 的后期构建步骤来完成的。虽然我个人不太喜欢这种解决方案。
  • 好的,谢谢。我同意这是一个相当烦人的解决方案。我必须在每个实施项目上手动配置构建后事件。你说使用 Unity 会演变成创建一个巨大的映射文件。我想我要测试 Unity 并比较哪个解决方案更好。
  • 您也可以只在项目之间创建引用,而不是使用统一。然后你不需要做任何其他事情。 (为了统一,您无论如何都需要创建参考)
猜你喜欢
  • 2012-12-06
  • 2010-11-14
  • 1970-01-01
  • 2011-01-28
  • 2013-07-24
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 2014-07-11
相关资源
最近更新 更多