简单的喷油器和装配扫描

Simple Injector and assembly scanning

我终于开始深入学习 IoC 和其他模式,并且 运行 在尝试根据程序集列表注册开放泛型时遇到了问题。我正在将我的框架的核心构建到单独的 class 库中,并有一组测试项目,我在其中声明一些测试 classes 继承自我的框架。

问题是 AddPersonCommandHandler : ICommandHandler<AddPersonCommand> 所在的 framework.test.service dll 在 运行 时没有加载,所以 ICommandHandler<> 开放式泛型找不到任何东西。我需要提前创建一个 AddPersonCommandHandler 实例,然后我在列表中得到一个额外的程序集,然后它就可以工作了。

有没有简单的强制加载方法?

=========== 编辑: 所以这是我的单元测试项目中的接线代码,它包含应用程序域和对其他程序集的引用。

public Container SetupIoc()
{
    var container = new Container();

    container.Register(typeof(IUnitOfWork), typeof(EntityFrameworkUnitOfWork), Lifestyle.Singleton);

    var assemblies = AppDomain.CurrentDomain.GetAssemblies();

    container.Register(typeof(ICommandHandler<>), assemblies);


    container.Verify();

    return container;
}

IUnitOfWork 在 Database.Interface.dll ICommandHandler<> 在 Core.dll AddPersonCommandHandler 位于 Test.Service.dll -- 一组项目的一部分设置结构模仿将真实解决方案放在一起并由单元测试引用。

所以,我认为单元或工作注册工作正常,因为我直接指定 UnitOfWork,而 ICommandHandler 接口位于成功绑定的核心中。 Post Verify() 我只看到 container 上的工作单元注册。要加载 Test.Service.dll 以便显示 AddPersonCommandHandler,我可以在我的 TestInit 方法中实例化一个 AddPersonCommand

不得不手动加载项目的所有 dll 似乎有点疯狂。就此而言,如果我扫描执行文件夹中的 dll,有些已经加载了...再次加载会很好地播放还是需要仔细检查以确定它是否已经加载?

您不必显式创建 AddPersonCommandHandler 的实例来确保程序集已加载。您所要做的就是在调用 AppDomain.CurrentDomain.GetAssemblies() 之前运行的代码中静态引用程序集中的一个类型(例如您的 AddPersonCommandHandler)。例如:

// Load BL assembly
Type type = typeof(AddPersonCommandHandler);

container.Register(typeof(ICommandHandler<>), AppDomain.CurrentDomain.GetAssemblies());

最好将此引用保留在您的 Composition Root 中。这确保无论从何处初始化容器(App_start 或集成测试)都加载相同的程序集。

更明确的方法是制作一个应该用于注册的程序集的明确列表:

// Adding the (redundant) namespace of the type makes it very clear to the
// user if this type is still located in the business layer.
Assembly[] businessLayerAssemblies = new[] {
    typeof(MyComp.MyApp.BusinessLayer.AddPersonCommandHandler).Assembly
}

container.Register(typeof(ICommandHandler<>), businessLayerAssemblies);
container.Register(typeof(IQueryHandler<,>), businessLayerAssemblies);
container.Register(typeof(IEventHandler<>), businessLayerAssemblies);
container.Register(typeof(IValidator<>), businessLayerAssemblies);

我更喜欢后一种方法,因为这可以防止扫描大量从不包含有用类型的程序集,同时对程序集非常明确(而不是隐式引用碰巧加载其程序集的类型)。