Hi Everyone,
I've came across a dilemma which I think is worth discussing here.
I have a set of domain objects (you can also call them entities, if you like), which get some data from a separate DAL which is resolved with an IoC.
I was thinking about making my system very extensible, and I'm wandering if it is right to also resolve these entities by the IoC.
Let me present a dumb example.
Let's say I have a web site for which I have the following interface:
public interface IArticleData
{
int ID { get; }
string Text { get; set; }
}
The concept is, that the DAL implements such interfaces, and also a generic IDataProvider<TData>
inteface, after which the DAL becomes easily replaceable. And there is the following class, which uses it:
public class Article
{
private IArticleData Data { get; set; }
public int ID
{
get { return Data.ID; }
}
public int Text
{
get { return Data.Text; }
set { Data.Text = value; }
}
private Article(IArticleData data)
{
Data = data;
}
public static FindByID(int id)
{
IDataProvider<IArticleData> provider = IoC.Resolve<IDataProvider<IArticleData>>();
return new Article(provider.FindByID(id));
}
}
This makes the entire system independent of the actual DAL implementation (which would be in the example, IDataProvider<IArticleData>
).
Then imagine a situation in which this functionality is not really enough, and I'd like to extend it. In the above example, I don't have any options to do it, but if I make it implement an interface:
public interface IArticle
{
int ID { get; }
string Text { get; set; }
}
public class Article : IArticle
{
...
}
And then, I remove all dependencies to the Article class and start resolving it as a transient IArticle component with an IoC.
For example, in Castle: <component id="ArticleEntity" service="IArticle" type="Article" lifestyle="transient" />
After this, if I have to extend it, that would be this simple:
public class MyArticle : Article
{
public string MyProperty { ..... }
}
And all I have to do is change the configuration to this: <component id="ArticleEntity" service="IArticle" type="Article" lifestyle="transient" />
So anyone who would use the system in question would be able to replace all classes as simply as rewriting a line in the configuration. All the other entities would work correctly also, because the new one would implement the same functionality as the old one.
By the way, this seems to be a good solution for the "separation of concerns" philosophy.
My question is, is this the right thing to do? After some serious thinking, I couldn't figure out any better way to do this. I also considered MEF, but it seems to be oriented to making plugins but not to replace or extend already complete parts of a system like this.
I read many SO questions (and also other sources) about the topic, the most notable are these: http://stackoverflow.com/questions/1405665/how-should-i-handle-my-entity-domain-objects-using-ioc-dependency-injection and http://stackoverflow.com/questions/109668/ioc-where-do-you-put-the-container
And I'm also afraid that I'm falling to the problems described on the following pages: http://martinfowler.com/bliki/AnemicDomainModel.html and http://hendryluk.wordpress.com/2008/05/10/should-domain-entity-be-managed-by-ioc/
And one more thing: this would increase the testability of the entire system, isn't it?
What do you think?
EDIT:
Another option would be to create a Factory pattern for these entities, but IoC.Resolve<IArticle>
is way simpler than IoC.Resolve<IArticleFactory>().CreateInstance()