使用Unity设置依赖注入,将类的实例传递给构造函数

本文关键字:实例 构造函数 设置 Unity 依赖 注入 使用 | 更新日期: 2023-09-27 18:11:24

我相信这里有我的问题的答案,虽然我只是不太明白我在寻找什么或我正在阅读什么…另外,在这种情况下,我不能100%确定DI是我应该使用的。

我正在尝试使用Unity为我的DI。我注入依赖到ASP。Net Web API控制器。到目前为止一切顺利。

我正在向控制器中注入控制器需要的服务。例如,在我的一个控制器中,我有:

private TransactionService _transactionService;
public TransactionsController(TransactionService transactionService)
{
    _transactionService = transactionService;
}

在这个例子中,我注入了一个TransactionService的实例到控制器中。

我的WebApiConfig.cs包含以下内容,据我所知,它实际上执行了注入:

   var container = new UnityContainer();
   container.RegisterType<ServiceBase>(new HierarchicalLifetimeManager());
   config.DependencyResolver = new UnityResolver(container);

如果需要,我可以给你看我的UnityResolver

现在我正在努力…

我的所有服务都继承自一个抽象类ServiceBase——它最简单的样子是这样的:

public abstract class ServiceBase : IDisposable
{
    internal Account _account;
    public ServiceBase(){}
} 

我想做的是在我的注入过程中创建Account并以某种方式传递它,以便我注入的服务不需要处理实例化帐户。

当我尝试向我的服务添加任何构造函数以接受Account时,我收到消息以确保我的控制器具有无参数构造函数。

. .我如何设置我的DI,以便我可以注入服务到我的控制器中,并注入Account的预实例化实例到我的服务中?

我忘了说(对不起,Wiktor) -如果可能的话,我不想使用属性。在我看来,这似乎很奇怪,我们可以使用DI来解除依赖,然后到处放置一堆依赖属性。我很可能只是没有正确理解DI的概念,尽管这对我来说似乎不正确

使用Unity设置依赖注入,将类的实例传递给构造函数

这应该很简单,只需将额外的属性设置为public,并在其上添加依赖属性。

 [Dependency]  
 public Account _account { get; set; }

Unity应该能够注入属性,你甚至可以注册Account类在一个普通的方式(例如注入工厂)。

我希望这能给你一些启发。

为服务基创建一个接口,并将account声明为公共属性。

服务接口:

you can also inherit other interfaces.
public interface ITransactionService : IDisposable
{
  IAccount Account{get;set;}
}

在你的类中实现它:

public class TransactionService : ITransactionService{
 private IAccount _account;
 public IAccount Account
 {
   get
     {if(_account==null)_account=new Account(); return _account;}
   set
     {_account=value;}
 }
}
现在在API控制器上使用构造函数,如下所示:
private ITransactionService _transactionService;
public TransactionsController(ITransactionService transactionService)
{
    _transactionService = transactionService;
}

统一解析器:

var container = new UnityContainer();
   container.RegisterType<ITransactionService,TransactionService>(new HierarchicalLifetimeManager());
   config.DependencyResolver = new UnityResolver(container);

所以用这种方式使用属性注入和构造函数注入来减少紧耦合依赖。

为单元测试模拟接口是很容易的。

您也可以为Account类创建一个接口,这样就可以很容易地根据您的使用进行模拟。

如果您不想使用属性,我完全同意,最好的方法是让ServiceBase接受account参数,如:

public abstract class ServiceBase {
  private Account _account;
  public ServiceBase(Account account) {
    this._account = account;
  }
}

您必须在派生服务上声明相同的构造函数以及TransactionService。当控制器被实例化时,Unity将首先正确地创建Account类的实例,然后通过构造函数注入将其传递给TransactionService对象。您应该使用生命周期管理器注册Account对象,将其范围设置为单例。