Dave is right, the goal of DI and IOC is to freely bind the components of your system.
Your user interface should know only about your domain, your domain should only know about your preservation, and your tenacity should know nothing about someone else.
Good .NET IoC containers are StructureMap (my preference), Ninject, and Castle Windsor.
There are several ways to implement DI / IoC, the most preferred way is to use interfaces.
You will have an interface for the Persistence layer:
public interface IPersistantStorage { List<Foo> GetStuff(); void AddStuff(Foo f); }
Similarly for your domain level:
public interface IDomainManager { List<Foo> GetStuff(); void AddStuff(Foo f); }
Then do specific classes for each.
Your selected IoC container will then βinjectβ specific classes into the constructor.
Here is an example of how it works with StructureMap:
public class SomeClassInUILayerThanNeedsToGetSomeThing { IDomainManager domain; public SomeClassInUILayerThanNeedsToGetSomeThing(IDomainManager realDomain) { this.domain = realDomain; } public List<Foo> GetSomethingFromSomewhere() { return domain.GetStuff(); } }
Then in the bootstrapper StructureMap (usually called in the application launch event - Global.asax)
public static void ConfigureIoCFramework() { ObjectFactory.Initialize(x => { x.For<IDomainManager>().Use<DomainManager>(); x.For<IPersistantStorage>.Use<NHibernateStorage>(); }); }
All that your user interface knows is its call to call some class Domain, which implements some interface. Your entire domain knows that it is going to name some Persistence class, which adds some interface.
How or What is handled by the DI container above.
How do you configure, which depends on your system. Usually I have this setting:
- Website β assembly links 2: general (extension methods, business entities, etc.), service (for example, a calling point from UI layers when caching to persistent storage, etc.)
- Tools β Links 1 Build: Repository
- Repository -> nothing links.
Then I would introduce the concrete implementation of the service level into the user interface and introduce the concrete implementation of the repository into the service level.
If you then look at your solution properties, look at a web project, you will see only 2 dependencies. In particular, it will not depend on the level of conservation.
If you want to go around objects, consider projecting your tables in POCO (contained in the general assembly).