gpt4 book ai didi

c# - 依赖注入(inject)的创建模式

转载 作者:太空狗 更新时间:2023-10-30 00:56:18 24 4
gpt4 key购买 nike

我专门将 C# 与 Ninject 结合使用,但问题不仅仅局限于 Ninject。我的问题是我有几个类都有不同的构造函数参数加上注入(inject)的参数。我知道我可以使用 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; }
}

我知道在 Ninject 中我可以执行以下操作:

kernel.Get<Car>(new ConstructorArgument("key", 1), new ConstructorArgument("year", 2010), new ConstructorArgument("make", "Astin Martin"), new ConstructorArgument("model", "Vanquish"));

但这对我来说并不合适。我想做的是将其更改为具有 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);
}
}

问题:“可能的新东西”是一种常见的做法、坏主意、好主意但实现不力,还是有更好的方法来完成它?

最佳答案

您不应该将 IStore 注入(inject)到您的 DTO 中。它们应该是普通对象。而是注入(inject) 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);
}
}

此外,不应使用 IoC 容器创建像 Person 这样的 DTO。从持久层获取它们,使用 AutoMapper 创建它们或使用 new 创建它们.但不要为它们使用 IoC 容器。他们不应该有任何依赖关系。

关于c# - 依赖注入(inject)的创建模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8155686/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com