如何在使用Unity IoC容器时注入属性?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在使用Unity IoC容器时注入属性?相关的知识,希望对你有一定的参考价值。

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

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

现在,我有一个看起来像这样的课程

using Project1.Foundation.Contracts;
using Project2.Respositories.Contracts.UnitsOfWork;
using Unity.Attributes;

namespace Project2.Presenters.Bases
{
    public class BasePresenter
    {
        [Dependency]
        public IUserPassport Passport { get; set; }

        [Dependency]
        public IUnitOfWork UnitOfWork { get; set; }
    }
}

Project2.dll中,我在上面提到的两个属性中添加了[Dependency]属性。但是,当应用程序运行时,两个属性都为null,而不是设置为实例。

我也尝试使用InjectionProperty而不是像这样添加[Dependency]

container.RegisterType<BasePresenter>(new InjectionProperty("Passport", new ResolvedArrayParameter<IUserPassport>()),
                                      new InjectionProperty("UnitOfWork", new ResolvedArrayParameter<IUnitOfWork>()));  

但是,我仍然得到相同的结果,当类构造像new ChildPresenter()这两个属性仍然是null。

背景

这是我如何从不同的程序集(Project1.dll)注册所需的类型,在UnityConfig类中,我有以下方法。

public static void RegisterTypes(IUnityContainer container)
{
    container.RegisterType<IUnitOfWork, UnitOfWork>(new ContainerControlledLifetimeManager());
    container.RegisterInstance<IPrincipal>(Thread.CurrentPrincipal);
    container.RegisterType<IUserPassport, UserPassport>(new ContainerControlledLifetimeManager());
}

换句话说,我在一个程序集中创建IoC并且我想在不同的程序集中使用它不确定它是否重要,我只是认为它应该是快速问题的一部分。

如何使用Unity.Mvc IoC容器正确注入属性?

回复以下评论

下面评论的问题:为什么我不能只在构造函数中传递参数?

如果我这样做,我的代码将如下所示

public class ConsumerController
{
    protected IUserPasspoer Passport { get; set; }
    protected IUnitOfWork UnitOfWork { get; set; }

    public ConsumerController(IUserPasspoer passport, IUnitOfWork unitOfWork)
    {
        Passport = passport;
        UnitOfWork = unitOfWork;
    }

    public ActionResult Index(int? id)
    {
        var presenter = new SomeIndexPresenter();

        return View(presenter);
    }

    public ActionResult Create(int? id)
    {
        var presenter = new ChildPresenter(Passport, UnitOfWork);

        return View(presenter);
    }

    public ActionResult Create(ChildPresenter presenter)
    {
        if(ModelState.IsValid)
        {
            presenter.Save();
            return ReditectToAction("Index");
        }

        return View(presenter);
    }
}

public class BasePresenter
{
    protected IUserPasspoer Passport { get; set; }
    protected IUnitOfWork UnitOfWork { get; set; }

    public ConsumerController(IUserPasspoer passport, IUnitOfWork unitOfWork)
    {
        Passport = passport;
        UnitOfWork = unitOfWork;
    }
}

public class ChildPresenter : BasePresenter
{
    public ConsumerController(IUserPasspoer passport, IUnitOfWork unitOfWork)
      :base (passport, unitOfWork)
    {
    }
}

另一方面,如果我可以利用属性注入,这应该是使用Ioc的好处之一,那么我的代码将看起来像这样

public class ConsumerController : Controller
{
    public ActionResult Index(int? id)
    {
        var presenter = new SomeIndexPresenter();

        return View(presenter);
    }

    public ActionResult Create(int? id)
    {
        var presenter = new ChildPresenter();

        return View(presenter);
    }

    [HttpPost]
    public ActionResult Create(ChildPresenter presenter)
    {
        if(ModelState.IsValid)
        {
            presenter.Save();
            return ReditectToAction("Index");
        }

        return View(presenter);
    }
}

public class BasePresenter
{
    [Dependency]
    protected IUserPasspoer Passport { get; set; }

    [Dependency]
    protected IUnitOfWork UnitOfWork { get; set; }
}

public class ChildPresenter : BasePresenter
{
}
答案

如果你new ChildPresenter,Unity没有参与,也不会注入任何东西。

您必须使用构造函数参数注入属性,然后:

public ActionResult Create(int? id)
{
    var presenter = new ChildPresenter()
        {
            Passport = Passport,
            UnitOfWork = UnitOfWork
        };

    return View(presenter);
}

在我看来,构造函数参数变体看起来更好......

以上是关于如何在使用Unity IoC容器时注入属性?的主要内容,如果未能解决你的问题,请参考以下文章

IoC 依赖注入容器 Unity

如何在Signal I hub的Unity IoC容器中注入依赖项?

IoC之Unity

IOC小结

Unity容器在asp.net mvc中的IOC应用及AOP应用

运用Unity实现依赖注入[结合简单三层实例]