为使用UnityConfiguration扫描仪完成的注册设置生存期管理器

为使用UnityConfiguration扫描仪完成的注册设置生存期管理器,configuration,dependency-injection,unity-container,Configuration,Dependency Injection,Unity Container,我有一个ASP.NET MVC4应用程序,正在使用Unity for IOC。我正在使用Unity.MVC4和unityconfigurationnumget包来帮助注册 我需要自动将一堆接口及其相关类型注册到Unity容器中。为此,我创建了一个虚拟接口;IDependencyInjectionScanner,我的所有真实接口都从中继承。下面的代码显示了这一点 public interface IDependencyInjectionScanner { } public interface

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

我需要自动将一堆接口及其相关类型注册到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();
        });
Scan(扫描=>
{
scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,“bin”);
用()扫描;
包括(x=>(x.GetInterface(typeof(IDependencyInjectionScanner.Name)!=null));
scan.ForRegistries();
});
问题是,我想使用分层生存期管理器注册扫描器找到的所有类型,但我可以想出如何做到这一点。UnityConfiguration的GitHub页面指出,这可以通过以下代码实现:

Configure<IChair>().AsHierarchicalControlled();
Configure().AsHierarchicalControlled();
但是,如果我必须为扫描仪绑定的每个接口执行此操作,那么扫描仪没有任何用处,我也可以这样做:

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

有人能帮我找到解决办法吗?

正如@TylerOhlsen所建议的那样,我使用了Unity 3.0的内置按约定注册功能。我已经添加了注册映射,它们正在使用分层生命周期管理器。下面是代码

container.RegisterTypes(
      AllClasses.FromLoadedAssemblies().Where(
        t => t.GetInterface(typeof(IDependencyInjectionScanner).Name) != null),
      WithMappings.FromMatchingInterface,
      WithName.Default,
      WithLifetime.Hierarchical);
有一件事困扰着我;当我查看注册时,我有4个(基于上面的示例代码)。椅子类型有2个类型映射,桌子类型有2个类型映射


谁能解释一下为什么会这样,因为我只希望有两个映射。

下面是使用UnityConfiguration对您的问题的答案。您可以创建自定义约定来配置生存期。只是要小心,因为Scan()方法中的调用看起来是顺序相关的

public class HierarchicalLifetimeConvention : IAssemblyScannerConvention
{
    public void Process(Type type, IUnityRegistry registry)
    {
        registry.Configure(type).AsHierarchicalControlled();
    }
}
然后将其添加到Scan()调用中

Scan(扫描=>
{
scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,“bin”);
用()扫描;
scan.With();/(x.GetInterface(typeof(IDependencyInjectionScanner.Name)!=null));
scan.ForRegistries();
});

我鼓励您了解Unity 3.0及其内置功能。这会解决你的问题,但使用一种完全不同的方法,这对你来说可能是不可能的。我以前确实看过,但无法让它发挥作用。我会在某个时候重新审视它,根据,这是设计的。它使用WithMappings.*func配置的所有类型注册每个类型,并使用指定的生存期和注入成员自行注册该类型。(即,一次用于将类型映射到其接口,一次用于将类型映射到其自身)
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();
    });