简单的进样器和装配扫描

时间:2016-08-08 09:46:13

标签: c# .net dependency-injection simple-injector

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

问题是framework.test.service dll其中AddPersonCommandHandler : ICommandHandler<AddPersonCommand>未在运行时加载,因此ICommandHandler<> open generic无法找到任何内容。我需要提前创建一个AddPersonCommandHandler实例,然后在我的列表中获得一个额外的程序集,然后它就可以了。

是否有一种强制加载的简单方法?

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

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中 - 一系列项目设置的一部分,模仿将实际解决方案放在一起并由单元测试引用。

所以,正在发生的事情是单元或工作注册工作正常我认为因为我直接指定UnitOfWorkICommandHandler接口在Core中成功绑定。发布验证()我只在container上看到工作单位注册。要加载Test.Service.dll以便AddPersonCommandHandler显示,我可以在我的TestInit方法中实例化AddPersonCommand

这似乎只是一点点疯狂有手动加载该项目所有的DLL。对于这个问题,如果我扫描执行文件夹中的dll,有些已经加载...将再次加载可以很好地运行还是需要仔细检查以确定它是否已经加载?

1 个答案:

答案 0 :(得分:3)

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

// 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);

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