c# - 使用 Unity IoC 配置 'deep' 依赖项

标签 c# .net asp.net-mvc asp.net-mvc-2 inversion-of-control

假设我的 MVC 2 项目中有以下类和接口(interface):

存储库:

IRepository1、IRepository2、IRepository3

public class ConcreteRepository1 : IRepository1
{
     public ConcreteRepository1()
     {
         ...
     }
     ...
}

public class ConcreteRepository2 : IRepository2
{
     public ConcreteRepository2()
     {
         ...
     }
     ...
}

public class ConcreteRepository3 : IRepository3
{
     public ConcreteRepository3()
     {
         ...
     }
     ...
}

服务类别:

public class Service1
{
    private IRepository1 repo1;
    private IRepository2 repo2;

    public Service1(IRepository1 repo1, IRepository2 repo2)
    {
        this.repo1 = repo1;
        this.repo2 = repo2;
    }
    ...
}

Controller :

public class Controller1 : Controller
{
    private Service1 srv1;
    private Service2 srv2;

    public Controller1(Service1 srv1, Service2 srv2)
    {
        this.srv1 = srv1;
        this.srv2 = srv2;
    }
    ...
}

我有自定义 ControllerFactory,我知道如何将具体存储库绑定(bind)到接口(interface):

IUnityContainer container = new UnityContainer();
container.RegisterType<IRepository1, ConcreteRepository1>(new TransientLifetimeManager(), new InjectionConstructor());
container.RegisterType<IRepository2, ConcreteRepository2>(new TransientLifetimeManager(), new InjectionConstructor());
container.RegisterType<IRepository3, ConcreteRepository3>(new TransientLifetimeManager(), new InjectionConstructor());

问题是我应该如何在我的自定义 ControllerFactory 中注册服务的实例和 Controller 的类型以使统一容器解析整个层次结构 Controller->Service->Repository 并避免在 Controller 或服务中调用 Resolve?

谢谢。

最佳答案

如果您已经注册IRepository1-3 , 所以你可以得到 Service1实例简单调用

container.Resolve<Service1>()

调用 container.Resolve<Controller1>()将自动解析依赖关系并创建 Controller1 类型的实例.

示例:

public interface IRepository1 { }
public interface IRepository2 { }
public interface IRepository3 { }

public class ConcreteRepository1 : IRepository1 { }
public class ConcreteRepository2 : IRepository2 { }
public class ConcreteRepository3 : IRepository3 { }

public class Service1
{
    private IRepository1 repo1;
    private IRepository2 repo2;

    public Service1(IRepository1 repo1, IRepository2 repo2)
    {
        this.repo1 = repo1;
        this.repo2 = repo2;
    }
}

public class Service2
{
    private IRepository1 repo1;
    private IRepository2 repo2;

    public Service2(IRepository1 repo1, IRepository3 repo3)
    {
        this.repo1 = repo1;
        this.repo2 = repo2;
    }
}

public class Controller1
{
    private Service1 srv1;
    private Service2 srv2;

    public Controller1(Service1 srv1, Service2 srv2)
    {
        this.srv1 = srv1;
        this.srv2 = srv2;
    }
}

正在解决:

var container = new UnityContainer();
container.RegisterType<IRepository1, ConcreteRepository1>();
container.RegisterType<IRepository2, ConcreteRepository2>();
container.RegisterType<IRepository3, ConcreteRepository3>();

var controller = container.Resolve<Controller1>();

编辑:

public interface IRepository { }
public class Repository : IRepository { }

public class Service
{
    //[InjectionConstructor]
    public Service()
    {
        Console.WriteLine("Parameterless constructor called");
    }

    public Service(IRepository repository)
    {
        Console.WriteLine("Contructor with IRepository called");
    }
}

private static void Main()
{
    var container = new UnityContainer();
    container.RegisterType<IRepository, Repository>();
    var service = container.Resolve<Service>();
    container.RegisterType<Service>(new InjectionConstructor());
    var service2 = container.Resolve<Service>();
}

输出:

Contructor with IRepository called
Parameterless constructor called

所以,当我们还没有注册时Service (换句话说,它具有默认解析行为),Unity 构造 Service默认使用最贪婪的构造函数。当您指定 new InjectionConstructor() ,这告诉 Unity 使用无参数构造函数。如果将构造函数(在本例中为 public Service() )标记为 InjectionConstructorAttribute ,则可以收到相同的行为。 .

关于c# - 使用 Unity IoC 配置 'deep' 依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7647923/

相关文章:

javascript - 加载图像不显示

c# - 是否有超过 4 个参数的 Func 对象?

c# - 如何为 <asp :button>? 的访问 key 添加下划线

javascript - 与 CruiseControl、nUnit、nAnt 和 ASP.net MVC 集成的 Javascript 自动化单元测试

c# - jquery ajax 调用 JsonResult Controller 方法导致 IIS6 上的 404

c# - 无法将 'Microsoft.NETCore.App (>= 2.0.0)' 解析为 '.NETCoreApp,Version=v2.0'

c# - 关于什么可能导致 System.Timers.Timer.set_Enabled 属性抛出 System.NullReferenceException 的任何想法?

c# - 如何从下拉列表中获取选定的值 C# ASP.NET

c# - 在 Python 中压缩并使用解压缩 C# 解压缩的最简单方法(反之亦然)

javascript - 使用多个下拉列表在单个 View 中过滤具有两个模型的数据表