0

我有一个 ASP.NET MVC4 应用程序,并且正在为 IOC 使用 Unity。我正在使用 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 的 GitHub 页面https://github.com/thedersen/UnityConfiguration指出这可以通过以下代码实现:

Configure<IChair>().AsHierarchicalControlled();

但是,如果我必须对扫描仪绑定的每个接口都这样做,那么扫描仪就没有用了,因为我也可以这样做:

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

有人可以帮助我找到解决方案吗?

4

2 回答 2

0

正如@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 个类型映射。

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

于 2013-09-07T19:24:11.723 回答
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();
    });
于 2013-09-07T19:59:02.827 回答