依赖注入在哪里使用“new”运算符

时间:2013-09-07 07:58:44

标签: c# dependency-injection

我使用依赖注入是“新手”,我的问题是:我在哪里可以使用new运营商?在下文中,我将向您展示一个示例,我想知道我是否正确使用new运算符。

示例适用于带有CustomControllerFactory的ASP.NET MVC,到目前为止一切正常。

首先,我有我的实体班Member

public partial class Member
{
    public Member()
    {
        this.LoginTries = 0;
    }

    public int Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public DateTime CreationDate { get; set; }
    public int LoginTries { get; set; }
}

然后有一个用户操作的界面:

public interface IDiMembership<TUser>
{
    bool Login(string username, string password, bool rememberMe = false);
    void Logout();
    //This is the Function I am using later and where i am using the new Operator
    bool CreateUser(string username, string password, TUser user);
    ...
}

我的界面实现:

public class DiMembership : IDiMembership<Member>
{
    ...
    public bool CreateUser(string username, string password, Member user)
    {
        user.PasswordSalt = Crypto.GenerateSalt();
        user.Password = Crypto.HashPassword(
            string.Format("{0}{1}", password, user.PasswordSalt));
        user.Username = username;
        user.CreationDate = DateTime.Now;
        ...
     }

我的Controller电话,以及我的问题是:用新的“会员”调用CreateUser方法或创建新的Member对象预填充权是正确的一些价值观?这个DI是否符合或如何解决问题?

private readonly IDiMembership<Member> _membership;
public AccountController(IDiMembership<Member> membership)
{
        _membership = membership;
}

public ActionResult Register(RegisterModel model)
{
    if (ModelState.IsValid && 
        _membership.CreateUser(model.Username, model.Password, new Member()))
    {
       return RedirectToAction("RegisterSuccess");
    }
     ...
 }

2 个答案:

答案 0 :(得分:1)

有些DI框架为此提供了工厂,因此您无需致电new运营商。例如,Castle Windsor提供Typed factories

有了这个,你只需定义界面:

public interface IUserFactory
{
  public IUser CreateUser(string username, string password...);
}

将该接口注册为工厂。 Windsor将提供此接口的实现,它将匹配以下类中的以下构造函数(假设您将User注册为组件):

public class User : IUser
{
  public User(string username, string password ...)
  {

  }

}

逻辑上,您的控制器还必须将此工厂声明为依赖项。

public class AccountController
{
  private IUserFactory _userFactory;

  public AccountController(IUserFactory userFactory)
  {
    _userFactory = userFactory;
  }

  public ActionResult Register(RegisterModel model)
  {
    IUser user = _userFactory.CreateUser(model.Username, model.Password);
    ...
  }
}

但是,如果您没有使用任何框架,或者您的框架没有提供工厂实现,那么您可以编写自己的工厂,它们包含对组件容器的引用,并且能够在您调用时解析IUser他们的Create方法。

这样,您就不需要调用new运算符来实例化新对象作为控制器逻辑的一部分。

答案 1 :(得分:1)

我会建议以下方法:

  • 复杂对象(需要一些业务逻辑或复杂过程才能正确初始化的对象)应该通过工厂创建
  • 可以在任何地方创建足够简单的对象(例如DTOPOCO

如果你的RegisterModel只存储了几个简单的值,那就没有必要将它的创建委托给工厂了,因为它太过拉伸和不必要的类创建。

您是否使用stringintDateTime的工厂?不。但是,只要这些简单的值被提升到更高的复杂程度或附加了一些业务逻辑,我们就会从 newing 切换到专用对象进行创建 - 考虑StringBuilder或{ {1}}。