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

时间:2018-02-28 16:45:24

标签: c# asp.net-mvc dependency-injection asp.net-mvc-5 unity-container

我正在尝试在我的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()时,两个属性仍为空。

背景

以下是我从不同程序集(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
{
}

1 个答案:

答案 0 :(得分:0)

如果您new ChildPresenter,则Unity不会参与,也不会注入任何内容。

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

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

    return View(presenter);
}

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