Reputation: 3428
I'm "new" at using Dependency Injection and my question is: where can I use the new
Operator? In the following I will show you an example, and I like to know if I use the new
operator correctly.
The Example is for ASP.NET MVC with a CustomControllerFactory
, everything works fine so far.
First I have My Entity Class 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; }
}
Then there is a interface for some user actions:
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);
...
}
My implementation for my interface:
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;
...
}
And my Controller
call, and here is also my question is: it right to call the CreateUser
method with a new "Member" or to create a new Member
Object an prefill some values? Is this DI conform or how to solve the problem right?
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");
}
...
}
Upvotes: 1
Views: 1062
Reputation: 31464
I would advice following approach:
If your RegisterModel
is only storing several simple values, there's no point to delegate its creation to factory as it's too much stretch and unnecessary classes creation.
Do you use a factory for string
, int
or DateTime
? No. But as soon as those simple values get promoted to some higher level of complexity or have some business logic attached we switch from newing them to dedicated objects for creation - think about StringBuilder
or Random
.
Upvotes: 1
Reputation: 68710
Some DI frameworks provide factories for this purpose, so you won't ever need to call the new
operator. For example, Castle Windsor provides Typed factories.
With this, you'd just define the interface:
public interface IUserFactory
{
public IUser CreateUser(string username, string password...);
}
And register that interface as a factory. Windsor will provide the implementation for this interface, which will match the following constructor on the following class (assuming you registered User as a component):
public class User : IUser
{
public User(string username, string password ...)
{
}
}
Logically, your controller would also have to declare this factory as a dependency.
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);
...
}
}
If, however, you're not using any framework, or your framework doesn't provide factory implementations, then you could write your own factories, which hold a reference to your components container and are able to resolve IUser when you call their Create
methods.
This way, you won't need to call the new
operator to instantiate new objects as part of your controller's logic.
Upvotes: 1