IoC Dsl – The Beginning

25 02 2008

First of all, before you begin to wonder what IoC Dsl stands for: IoC Dsl stands for Inversion of Control Domain specific language, not for International Olympic Committee. Secondly, IoC isn’t something new. It came from the java world (the Others …) and nowadays it’s a hot topic in .NET. IoC is something we use every day without even realizing it. It’s about loading certain implementations of an interface without you knowing in code which implementation you loaded.

Why build an IoC Dsl?

Before I go into detail on IoC, I’ll give you a little explanation why IoC is important for us, IntoFactories laborers. Our main goal is getting into all cool things like DSL, Guidance Automation Toolkit and any other Software Factory technologies. Because we want to build a Factory that builds something, we chose to create a DDD Software factory. Now any DDD implementation needs an IoC container. Why? Simple. One of the rules of DDD is that the Infrastructure Layer (ex an ORM) knows the Domain Layer and the Domain Layer doesn’t know the infrastructure Layer. Solution: IoC to the rescue!

Inversion of Control

Inversion of Control is all about loading the right plugin implementation and injecting it in your running code. IoC is a too generic term, from a simple logging provider that is loaded (ex the Entlib logging) to advanced IoC containers as Spring.Net or Castle. The term dependency injection is therefore closely coupled to IoC.

There are 3 forms of dependency injection:

  • Constructor Injection: Injects an instance of class A into class B using the constructor of B
  • Property Injection: Injects an instance of class A into class B by setting a Property of B
  • Interface Injection: An interface that describes how an instance needs to be injected

Every IoC container is built on the same 3 pillars:

  • Configuration file: A file that describes which components are hosted by the IoC container.
  • Assembler: Component responsible in loading the right implementation and injecting the necessary dependencies.
  • Object lifestyle manager: Every IoC container has the possibility to manage the lifestyle of an object. Commonly supported lifestyles are singleton and single call.

Most of the IoC containers also support aspect oriented programming (also called policy injection after the Policy Injection Block in EntlLib 3.1). This allows you to handle cross cutting concerns like logging, security and transactions of the in the IoC Container hosted objects.

The frameworks

There are a lot of available frameworks in the open that support dependency injection:

The following posts will handle these frameworks.

Back to the main topic!

What part of IoC and dependency injection can we automate in our Software Factory and technical framework? First off all, abstraction of external components is always a best practice. This will prevent assembly references to 3rd party frameworks in your projects and will ease the integration of a newer version. That’s typically a job for a technical framework. We will make the assumption that every AppDomain will contain only one instance of an IocContainer. By creating a static gateway to the IoC container we can hide its implementation. Because every architecture is different, we have to allow the user to choose which implementation of the IoC container he wants to use. This can be easily done by a provider mechanism.

Now let’s go to the cool stuff! The generation of the config file can be done with a Dsl. This Dsl needs to be able to generate the possible humongous config files for the different IoC Container implementations. Next thing that would be cool is single-click “Host in IoC” option provided by GAT… Ok, the requirements are almost set, so let’s start building the IoC Dsl/GAT package.

The following days/weeks I will write some posts about the different IoC implementations on the market, starting with Unity. See you next time!

Greetz,
Thomas


Actions

Information

8 responses

25 02 2008
Leo

Even a dummy in IoC can understand now what this is about. Thx.

26 02 2008
gcool

indeed, but still, a picture tells a thousand words, please draw us something Thomas !

26 02 2008
tannerel

Owke I’ll try to make some time for a follow up post including some images about ioc and some extra concepts

27 02 2008
Steve Degosserie

“Before I go into detail on IoC, I’ll give you a little explanation why IoC is important for us, IntoFactories laborers. Our main goal is getting into all cool things like DSL, Guidance Automation Toolkit and any other Software Factory technologies. Because we want to build a Factory that builds something, we chose to create a DDD Software factory. Now any DDD implementation needs an IoC container. Why? Simple. One of the rules of DDD is that the Infrastructure Layer (ex an ORM) knows the Domain Layer and the Domain Layer doesn’t know the infrastructure Layer. Solution: IoC to the rescue!”
-> The point of DDD is to focus on the business : the model (structure), the behaviors (logic) and the rules (specifications). DDD is not about ‘getting into cool technical stuff’, also, any DDD implementation doesn’t ‘require’ an IoC Container.

“Inversion of Control is all about loading the right plugin implementation and injecting it in your running code”
-> Inversion of Control is not ‘just’ about dependency injection. IoC is about breaking dependencies, about building loosely-coupled architectures. Dependency Injection is a pattern that helps applying IoC in your application/framework.

“The generation of the config file can be done with a Dsl. This Dsl needs to be able to generate the possible humongous config files for the different IoC Container implementations.”
-> Don’t you feel there is something wrong with that sentence? If you have to build a Dsl to be able to generate configuration files for your IoC container(s) … isn’t the problem coming from your container ? A good IoC container should not require ‘humonguous’ configuration files to configure your components and ‘declare their dependencies’. You already ‘declared’ the dependencies of your components in the code itself (arguments in constructors, public properties). Using acceptable defaults & convention over configuration will spare you a lot of time. Use a good container -> Castle Windsor :o )

27 02 2008
Goeleven Yves

Steve,

You’re absolutly right on all of your remarks, but…

If you want to develop a DDD app, you will run into the problem that your Domain must know what the resource layer looks like so that it can call on its methods. On the other hand, your resource layer needs to know about the structure of your domain so that it can make decent decissions on persistence.

In my opinion this is only possible to achieve when the resources like repositories are injected into the domain. This way you have a direct dependency from the resource layer to the domain layer and an indirect dependency from the domain to the resources.

Additionaly, this setup allows for unittesting of the domain layer even before the resource layer is even written.

Doing DDD, does not ‘require’ an ioc, but it does need DI, be it a service locator or an IoC container.

27 02 2008
Steve Degosserie

Hello Yves,

I agree, in general, DDD needs DI … I was just being picky on the ‘require’ word ;o) lol

About the coupling of the Domain Model & what you call Resources (Repositories), there is an ongoing debate about whether Eric Evans is right to say that the Domain should have knowledge of the Repositories, and whether Repositories are actually different than DAOs.
-> Christian Bauer & Gavin King, creators of Hibernate, seem to think that keeping the Domain Model free from persistence-related logic at all costs is mandatory to reach complete Persistence Ignorance:
http://in.relation.to/Bloggers/RepositoryPatternVsTransparentPersistence
http://in.relation.to/Bloggers/StillConfusedAboutRepositories

I, personnaly, prefer their pragmatic approach. I try to put as much as possible in the Domain Model (Entities, Specifications, Business Rules), while still keeping above it, a Service layer that will make use of the Domain & the Repositories as needed.

Using IoC & DI, you can, indeed, unit test any layer separately.

27 02 2008
Goeleven Yves

Steve,

In my opinion, the repository interface, belongs to the domain layer as the entities and domain services need to know these methods in their internal implementation. If you want to ask the Customer for its TotalAmountBought, it will need to fetch all its orders. And that’s what the implementation of the repository does, fetch all associated orders, no matter where the orders come from. Logic like this should be defined inside the boundaries of the aggregate, not in some service in another layer… Higher level services, in the application layer for example, should only access business logic via the aggregate roots which are exposed by a repository.

The actual implementation of the repository methods belong to the resource layer, it will probably need to know about the details of the medium where the object can be retrieved from. In this light, you can see that a repository has nothing to do with a DAO, it may use a DAO to actually fetch the object from a database, but it may look into some in memory cache first. In really big applications, google size for example, it’s really unlikely that a repository will go to a database, it will probably read the data from a distributed grid or some other faster medium.

In regards of persistence ignorance: Repositories have nothing to do with persistence, they are about single points of access for entities and aggregates. So even when using persistence ignorant frameworks like NHibernate, I would still put a repository above it so that my domain can still get the data it needs from the repository, be it from NHibernate, a set of DAO’s, a file system or even a distributed grid.

27 02 2008
Steve Degosserie

Yves,

I answer you by email … I guess we’re shifting away from the topic of the article ;o) lol

Leave a comment