1

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

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

首先我有我的实体类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");
    }
     ...
 }
4

2 回答 2

1

一些 DI 框架为此提供了工厂,因此您永远不需要调用new操作员。例如,Castle Windsor 提供了Typed factory

有了这个,你只需定义接口:

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);
    ...
  }
}

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

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

于 2013-09-07T08:13:50.277 回答
1

我建议以下方法:

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

如果您RegisterModel只存储几个简单的值,那么将它的创建委托给工厂是没有意义的,因为它过多的拉伸和不必要的类创建。

你使用工厂stringint还是DateTime?不。但是一旦这些简单的值被提升到更高级别的复杂性或附加了一些业务逻辑,我们就会从新建它们切换到用于创建的专用对象——想想StringBuilderRandom

于 2013-09-07T08:30:19.020 回答