如何注册实现UnityContainer相同接口的多个类?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何注册实现UnityContainer相同接口的多个类?相关的知识,希望对你有一定的参考价值。

我正在尝试在我的Asp.Net MVC 5应用程序中设置IoC容器,这样我就可以在我的应用程序中的任何位置访问这些对象。

我选择使用Unity.Mvc容器来完成这项工作。

我想使用反射或其他技术来自动注册我的程序集中实现名为IRunOnEachRequest的接口的任何类。

这就是我做的

我创建了以下接口

public interface IRunTask
{
    void Run();
}

public interface IRunAfterEachRequest : IRunTask
{
}

public interface IRunOnEachRequest : IRunTask
{
}

然后在UnityConfig.RegisterTypes方法,我试图做以下

var assemnlies = AppDomain.CurrentDomain.GetAssemblies().ToList();

foreach (Assembly assembly in assemnlies)
{
    try
    {
        var tasks = assembly.GetTypes().Where(x => x.IsClass && typeof(IRunTask).IsAssignableFrom(x)).ToList();

        foreach (Type task in tasks)
        {

            if (typeof(IRunAfterEachRequest).IsAssignableFrom(task))
            {
                //container.RegisterType<IRunAfterEachRequest, typeof(task)>();
            }
            else if (typeof(IRunOnEachRequest).IsAssignableFrom(task))
            {
                //container.RegisterType<IRunOnEachRequest, typeof(task)>();
            }
        }
    }
    catch
    {

    }
}

但线container.RegisterType<IRunAfterEachRequest, typeof(task)>();给我错误。

问题

  • 在UnityContainer中注册多种类型是否有更好的优雅需求?
  • 有没有办法使用默认约定自动注册?例如,如果我有一个名为IUnitOfWork的接口和当前程序集中名为UnitOfWork的实现“没有I的同名,则自动将它们注册到容器中。
答案

诀窍是按名称注册它们:

public interface IRunTask
{
    void Run();
}

public class RunTask1 : IRunTask { public void Run() { } }
public class RunTask2 : IRunTask { public void Run() { } }
public class RunTask3 : IRunTask { public void Run() { } }

执行代码:

var ctr = new UnityContainer();
var taskTypes = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass && typeof(IRunTask).IsAssignableFrom(x)).ToList();

// Register from IRunTask to T using T.Name as a unique key for the name. You can add additional params like a lifetimemanager etc.
taskTypes.ForEach(t => ctr.RegisterType(typeof(IRunTask), t, t.Name));
var tasks = ctr.ResolveAll<IRunTask>().ToList(); // RT1, RT2, RT3
tasks.ForEach(t => t.Run());

在UnityContainer中注册多种类型是否有更好的优雅需求?

我更喜欢通过配置文件注册,我从未使用Unity来解析具有相同界面的多种类型(我以前使用MEF做过这个,我不知道它是否仍然流行用于解析插件)。

有没有办法使用默认约定自动注册?例如,如果我有一个名为IUnitOfWork的接口和当前程序集中名为UnitOfWork的实现“没有I的同名,则自动将它们注册到容器中。

我不确定,但我认为你在这里遗漏了一些东西。 IOC的全部目的是创建多个类型(可以是单元测试,行为或多租户插件的模拟)。我不希望我的应用程序自动注册类型。 如果你仍然坚持,你可以创建一个默认属性,只需编写一些自动注册类型的反射代码。

以上是关于如何注册实现UnityContainer相同接口的多个类?的主要内容,如果未能解决你的问题,请参考以下文章

Unity Container 中基于 Marker 接口注册接口到不同的 Lifetime

UnityContainer中RegisterType与RegisterInstance的区别

Unity IOC容器通过配置实现类型映射的几种基本使用方法

如何在Asp.Net Core中注册同一接口的多个实现?

如何注册和使用同一接口的不同实现?

在 Unity Container 中注册 WCF 服务