Creating dependency injection patterns

I specifically use C # with Ninject, but the problem extends beyond Ninject only. My problem is that I have several classes with different constructor arguments plus the ones introduced. I know that I can use kernel.Get<MyObject>(constructor args here) to create objects. This does not seem right to me, since I will have a core everywhere. I will do my best to give examples below.

What I have now:

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

I know that in Ninject I can do the following:

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

but I donโ€™t like it. What I was going to do is change it to have an Initialize method, but I'm not sure if this is the best, or if there is a better way.

Possible new things:

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

Question: Is โ€œPossible New Materialโ€ a common practice, a bad idea, a good idea with a poor implementation, or is there a better way to do this at all?

+4
source share
1 answer

You should not enter IStore in your DTO. They should be ordinary objects. Instead, insert IStore<IThing> into the classes that currently call Update and call CommitToDatabase from there.

eg.

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

Also, DTOs like Person should not be created using an IoC container. Get them from the save layer, create them using AutoMapper or create them using new . But do not use an IoC container for them. They should not have any dependencies.

+6
source

Source: https://habr.com/ru/post/1381530/


All Articles