使用UnityConfiguration扫描程序设置生命周期管理器以完成注册

时间:2013-09-07 17:52:53

标签: configuration dependency-injection unity-container

我有一个ASP.NET MVC4应用程序,我正在使用Unity for IOC。我正在使用Unity.MVC4和UnityConfiguration Nuget包来帮助注册。

我需要自动将一大堆接口及其相关类型注册到Unity容器中。为此,我创建了一个虚拟接口;我所有真实接口继承的IDependencyInjectionScanner。以下是显示该代码的代码。

public interface IDependencyInjectionScanner
{

}

public interface IChair : IDependencyInjectionScanner
{
    NumberOfLegs { get; set; }
}

public class Chair : IChair
{
    public NumberOfLegs { get; set; }
}

public interface ITable : IDependencyInjectionScanner
{
    NumberOfChairs { get; set; }
}

public class Table : ITable
{
    public NumberOfChairs { get; set; }
}

然后我使用UnityConfiguration使用扫描程序绑定注册。我已经在控制器中正确解析了接口。下面的代码显示了我如何进行绑定。

Scan(scan =>
        {
            scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
            scan.With<FirstInterfaceConvention>();
            scan.Include(x => (x.GetInterface(typeof(IDependencyInjectionScanner).Name) != null));
            scan.ForRegistries();
        });

问题是我想使用分层生命周期管理器注册扫描程序找到的所有类型,但可以弄清楚如何执行此操作。 UnityConfiguration https://github.com/thedersen/UnityConfiguration的GitHub页面指出这可以通过以下代码实现:

Configure<IChair>().AsHierarchicalControlled();

但是,如果我必须为扫描仪绑定的每个接口执行此操作,那么扫描仪就没用了,我可能会这样做:

Register<IChair, Chair>().AsHierarchicalControlled();

有人可以协助我找到解决方案。

2 个答案:

答案 0 :(得分:0)

正如@TylerOhlsen所建议的,我使用了Unity 3.0的内置注册功能。我有它添加注册映射,他们正在使用分层生命周期管理器。下面是那个

的代码
container.RegisterTypes(
      AllClasses.FromLoadedAssemblies().Where(
        t => t.GetInterface(typeof(IDependencyInjectionScanner).Name) != null),
      WithMappings.FromMatchingInterface,
      WithName.Default,
      WithLifetime.Hierarchical);

有一件事令我不安;当我看到我有4个注册(基于上面的示例代码)。用于Chair类型的2种类型映射和用于Table类型的2种类型映射。

任何人都可以解释为什么会这样,因为我只期待两次映射。

答案 1 :(得分:0)

以下是使用UnityConfiguration回答您的问题。您可以创建自定义约定来配置生命周期。请注意,因为看起来Scan()方法中的调用依赖于顺序。

public class HierarchicalLifetimeConvention : IAssemblyScannerConvention
{
    public void Process(Type type, IUnityRegistry registry)
    {
        registry.Configure(type).AsHierarchicalControlled();
    }
}

然后将其添加到您的Scan()调用...

Scan(scan =>
    {
        scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
        scan.With<FirstInterfaceConvention>();
        scan.With<HierarchicalLifetimeConvention>(); //<-- New convention
        scan.Include(x => (x.GetInterface(typeof(IDependencyInjectionScanner).Name) != null));
        scan.ForRegistries();
    });