1

在引导 StructureMap 时,我一直使用默认实例(而不是命名实例),并且能够定义一个简单的约定来由程序集扫描以连接实例。在不深入讨论公约本身的细节的情况下,我会像这样引导:

assemblies.ForEach(a =>
    x.Scan(y =>
    {
        y.Assembly(a);
        y.WithDefaultConventions();
        y.Convention<DomainInterfaceNamingConvention>();
    }));

assemblies我在初始化程序的其他地方放在一起的程序集列表在哪里,并且DomainInterfaceNamingConvention是我用于扫描这些程序集以将接口与实现匹配的自定义约定。

从我记事起,这一直运作良好。但是,现在我有理由使用命名实例。因此,例如,我可能会像这样引导我的记录器实现:

x.For<Logger>().Use(l => new Log4Net.LoggerImplementation());
x.For<Logger>().Add(l => new Log4Net.LoggerImplementation()).Named("Log4Net");
x.For<Logger>().Add(l => new NLog.LoggerImplementation()).Named("NLog");

因此定义了一个默认值,并添加了一些命名实例以防代码特别请求。

但是,我怎样才能将两者结合起来呢?在我的命名实例示例中,配置是按类进行的,而在我的基于约定的实例的示例中,配置是按程序集进行的。我的一些程序集中有很多类,在这种特殊情况下,这些类可以相当频繁地出现和消失。因此,需要手动连接每个类而不仅仅是每个程序集对于开发来说是一个不小的操作难题。

有没有办法在基于约定的扫描中在程序集级别命名?因此,例如,对于一个程序集,我可能有大量名为“Database”的引导存储库实例,对于另一个程序集,有一吨名为“XML”的实例,对于另一个程序集,还有一吨名为“Mock”的实例,而无需指定每个单独的存储库(三倍,如果算上默认值,四倍)在引导程序中?

4

1 回答 1

1

我最终使用了一点反思来实现这一点。无论如何,我倾向于约定而不是配置,我的程序集名称都遵循类似的模式。因此,例如,我可能有三个实现我的 DAL 接口的程序集:

  • Acme.Infrastructure.DAL.SQLExpress
  • Acme.Infrastructure.DAL.XMLFiles
  • Acme.Infrastructure.DAL.Mock

这里的最终目标是,在装配级别,我可以相应地配置命名实例。这样我就可以这样做:

var fooRepository = IoCFactory.GetInstance<FooRepository>("SQLExpress");
var barRepository = IoCFactory.GetInstance<BarRepository>("XMLFiles");

无需为每个存储库(整个代码库中的每个接口/类组合)添加单独的配置行到引导代码,因为这样维护起来很不直观,也不能很好地扩展。

因此,在我的约定扫描仪中,我只是获得了要在引导中使用的实现名称:

var implementationName = type.Assembly.GetName().Name.Split('.').Last();

然后,在其他一些逻辑中,将其添加到对象图中:

registry.For(interfaceType).Use(type).Named(implementationName);
于 2013-05-28T13:32:23.320 回答