Ale*_*oun 4 c# design-patterns dependency-injection ninject object-construction
我特意在Ninject中使用C#,但问题不仅仅是Ninject.我的问题是我有几个类都有不同的构造函数参数加上注入的类.我知道我可以kernel.Get<MyObject>(constructor args here)用来实例化对象.这对我来说并不合适,因为我的内核遍布整个地方.我会尽力列出下面的例子.
我现在拥有的:
public interface IStore<T>
{
void CommitToDatabase(T item);
}
public abstract class Thing
{
private IStore<Thing> _store;
protected Thing(object key, IStore<Thing> store)
{
Key = key;
_store = store;
}
public object Key { get; private set; }
public virtual void Update()
{
_store.CommitToDatabase(this);
}
}
public class Person :Thing
{
public Person(object key, string name, int age, IStore<Thing> store)
: base(key, store)
{
Name = name;
Age = age;
}
public string Name { get; private set; }
public int Age { get; private set; }
}
public class Car :Thing
{
public Car(object key, int year, string make, string model, IStore<Thing> store)
: base(key, store)
{
Year = year;
Make = make;
Model = model;
}
public int Year { get; private set; }
public string Make { get; private set; }
public string Model { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
我知道在Ninject我可以做到以下几点:
kernel.Get<Car>(new ConstructorArgument("key", 1), new ConstructorArgument("year", 2010), new ConstructorArgument("make", "Astin Martin"), new ConstructorArgument("model", "Vanquish"));
Run Code Online (Sandbox Code Playgroud)
但这对我来说并不合适.我想要做的是将其更改为具有Initialize方法,但我不确定这是最佳实践还是有更好的方法.
可能的新东西:
public interface IStore<T>
{
void CommitToDatabase(T item);
}
public abstract class Thing
{
private IStore<Thing> _store;
protected bool _isInitialised;
protected Thing(IStore<Thing> store)
{
Key = null;
_store = store;
_isInitialised = false;
}
public object Key { get; private set; }
public virtual void Initialize(object key)
{
if (!_isInitialised) {
Key = key;
_isInitialised = true;
}
}
public virtual void Update()
{
_store.CommitToDatabase(this);
}
protected bool IsInitialised()
{
return _isInitialised;
}
}
public class Person :Thing
{
public Person(IStore<Thing> store)
: base(store)
{
Name = string.Empty;
Age = int.MinValue;
}
public string Name { get; private set; }
public int Age { get; private set; }
public void Initialize(object key, string name, int age)
{
if (!base.IsInitialised()) {
Name = name;
Age = age;
}
base.Initialize(key);
}
}
public class Car :Thing
{
public Car(IStore<Thing> store)
: base(store)
{
Year = 0;
Make = "Ford";
Model = "Model T";
}
public int Year { get; private set; }
public string Make { get; private set; }
public string Model { get; private set; }
public void Initialize(object key, int year, string make, string model)
{
if (!base.IsInitialised()) {
Year = year;
Make = make;
Model = model;
}
base.Initialize(key);
}
}
Run Code Online (Sandbox Code Playgroud)
问题: "可能的新东西"是一种常见的做法,糟糕的想法,好的想法和糟糕的实施,还是有更好的方法来完成它?
你不应该把IStore注入你的DTO.它们应该是普通的物体.而是注入IStore<IThing>当前从那里调用Update和调用的类CommitToDatabase.
例如
public class PersonService
{
private readonly IStore<Person> store;
public PersonService(IStore<Person> store)
{
this.store = store;
}
public void CreatePerson(string name, int age)
{
var person = new Person(name, age);
this.store.CommitToDatabase(person);
}
}
Run Code Online (Sandbox Code Playgroud)
此外,不应使用IoC容器创建像Person这样的DTO.从持久层获取它们,使用AutoMapper创建它们或使用它们创建它们new.但是不要为它们使用IoC容器.他们不应该有任何依赖.
| 归档时间: |
|
| 查看次数: |
326 次 |
| 最近记录: |