views:

42

answers:

3

Hi,

My application is able to start without a database connection, how do I handle this with IoC and constructor injection?

Example:

public class ApplicationShellPresenter(IRepository repository, IView view)
{

}

When IRepository in this case will be constructed an exception will be thrown due to underlaying DAL cannot find config/file, wrong username/password etc. etc.

With this in mind I came to the conclusion that I cannot inject the repository in the constructor OR inject anything that eventually along the line have IRepository as dependency.

I need to start without IRepository dependency and when the user have made the correct database settings, register the IRepository in the container. But then I have already left the composition root.

Anyone got any idéa how to solve this?

Edit:

My problem was not really a IoC/Constructor injection - problem but rather a design flaw in our underlaying DAL.

Our DAL is constructing itself upon creation. And thats why that design didn't work because I couldn't construct a IRepository dependency without constructing our DAL-engine.

My simple solution was to wrap our DAL so it didn't construct itself upon creation.

+1  A: 

Take this a stage further. If I understand you correctly we have:

Application Starts

User specifies some database settings

Repository initialises, passwords etc are checked

Application now uses repository

My immediate thought is, hmmm, wonder whether we can also get

User decides "I don't like that repository"

User specified new database settings

New repository is initialised

Application closes previous repository, and starts working with new one.

Now it may be that this is slightly more flexible than you had planned, but it leads me to thing that you have effectively two applications, with a transient relationship between them. There's the "shell", which is independent of the repository, that's the bit that starts up without a repository. Then there's the extra piece that works only when it's got a repository, and I think is seems to be pluggable, at least in concept.

Hence I don't think your shell is so much being "Injected" as responding to interesting events such as:

Here is a repository, if you already have one please close it

Shut down, please close down your repository, and then yourself.

If you have a Event Interface I think you get what you need. The arrival of an Event is in effect an Injection.

djna
Thanks, interesting idéas.
Marcus
+1  A: 

See how I would do it.

Krzysztof Koźmic
Nice, I also came up with the factory aproach, but one thing is still bothering me. In my application I have lots of implementations requiring IRepository. How do I solve that with a factory? Do I have to wrapp every implementation that needs a IRepository with a class that takes a dependency on the IRepositoryFactory instead? Seems kind a awkward.
Marcus
what seems awkward is the fact that the repository needs configured and active connection to function. What ORM are you using? It feels very flawed.
Krzysztof Koźmic
I have figured it out now, our DAL we currently use was initalized when constructed and thats was our real problem, I just wrapped it into another class that wasn't initalized in the constructor and then I was able to inject IRepository in the application shell constructor without any problems.So this wasn't really a IoC problem when you look at it. But thanks anyway for your blog-post.
Marcus
happy to help :)
Krzysztof Koźmic
A: 

Siply use Setter Based Injection mechanism for IRepository rather using Constructor based injection mechanism.

saurabh