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?