1

I have layered asp.net MVC application. In the service layer, I have a container to register dependencies. e.g:

public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<ISomething, Something>();
    }

Based on the design, we need to have a mock implementation of the classes if the user decided to open the application for testing purpose.

So, I came up with an Idea like

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<ISomething, Something>();
        container.RegisterType<ISomething, SomethingMock>();
    }

If I use a flag somewhere to indicate whether or not system runs at testing mode, how can I make a decision on which dependency to resolve at the runtime? If it is not an elegant solution, what could be the alternative?

2 Answers 2

3

If I use a flag somewhere to indicate whether or not system runs at testing mode, how can I make a decision on which dependency to resolve at the runtime?

You should not change the structure of your object graph based on runtime decisions. This is very much related to the anti-pattern of injecting runtime data into components.

In case you require to switch implementations based on runtime conditions (meaning: the value might change from request to request), the solution is to create a proxy class that implements ISomething and wraps the two ISomething implementations (this article shows some examples of proxy implementations). When ISomething.Method is called, it can forward the call to the right implementation, based on the runtime condition that it determines at that point.

In your case however, you are most likely not talking about runtime conditions, but about a configuration value. Configuration values don't change during the lifetime of the application. Only after a restart (or redeploy) you would typically see a change of value.

That means that you can simply read the configuration value at startup and decide at that point which implementation should be registered:

if (bool.Parse(ConfigurationManager.AppSettings["Production"]))
{
    container.RegisterType<ISomething, Something>();
}
else
{
    container.RegisterType<ISomething, SomethingMock>();
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the reply. my case is the firs one. upon each request, I need to decide if its mock request or the real one. About the proxy class, please explain more. my service layer resolves business dependencies and each business needs some repository classes 'as data layers' to be injected to. now I need to mock only data layers.
@AhmadMousavi: Please update your question with additional information or post a new question on SO with the required details to answer this additional question. You can read more about how to implement such proxy in this article.
1

While I fully support Stevens answer and his considerations, there is technically a way to do what you intended. You can use named registration:

public static void RegisterTypes(IUnityContainer container)
{
    container.RegisterType<ISomething, Something>();
    container.RegisterType<ISomething, SomethingMock>("SomethingMock");
}

and then use a string parameter to resolve it:

string s= "";
var mySomething = container.Resolve<ISomething>(s);  // will return standard implementation
s = "SomethingMock"
var mySomething = container.Resolve<ISomething>(s);  // will return mock implementation

you would need to intercept when asp wants to resolve ISomething.

For reference see https://msdn.microsoft.com/en-us/library/ff660923%28v=pandp.20%29.aspx

Now it's up to you which way you go.

2 Comments

I am using unity 3.5 and it doesn't seem to be working for resolving named registrations.
I checked this with Unity 4.0.1 and it works fine but I think it should work with older versions too. What happens in your code? Maybe we can find out what's wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.