Creating a type with run time values

Jan 12, 2012 at 7:22 AM
Hi, Let's say I have a type defined as follows Public class Myclass :IMyclass { IComponent c; Public Myclass(string name, int age, IComponent comp) {...} } I would like to register and resolve this class using Unity. But I will have the values for the first 2 params only during run time which the user might input. So every time I resolve this, I want to instance to have the input values provided by the user. Is there a clean way to do this through constructor? Thanks in advance
Jan 12, 2012 at 8:03 AM

Do you know all parameters that are neccessary to create an instance of MyClass? Then it would be best practice to define a factory and inject that factory whereever you need it.

If some parameters still need to be resolved by Unity:

You can hand parameters to the container at resolve time. The Resolve method accepts ResolverOverrides that can be used to specify such information.

But I would strongly recommend that you don't call the container directly in your classes! It is better to define a factory interface like this

public interface IMyClassFactory
  IMyClass CreateInstance(string name, IComponent component);
and an implementation that can then use the container to create an object. Inject that interface into those classes that need to create instances of MyClass. This way the implementation of the factory which uses Unity directly is just an implementation detail the callers don't have to know about.

Jan 12, 2012 at 11:46 AM

Hi Weberse, 

Thank You for the reply. I am new to Unity and this tells me that Design Patterns are still valid even when using DI containers. When I read about DI, one thing I frequently see is what you mentioned here - "don't call the container directly in your classes!". Does that mean I should use a factory even when I need a simple component with dependencies that can be resolved completely by Unity(which doesn't need runtime values as in my original question)? Isn't that too much indirection?


Jan 12, 2012 at 11:56 AM

Using the DI container in the way you describe it means you are (ab)using is as a ServiceLocator. This is considered an anti-pattern in modern application architecture. See this blog post for a more detailed explanation.

Additionally: If you use the container directly you will polute your code with references to Unity (or another container). This should be a no-go! What if you want (or have to) switch your container for something else?

Declaring factory interfaces and injecting those enables another interesting scenario. You can let your container generate those factories for you instead of writing and maintaining them yourself. There is an implementation for this feature in the TecX project.

If you are interested in a detailed introduction to the DI pattern you should have a look at Dependency Injection in .NET by Mark Seemann.

Jan 13, 2012 at 4:36 AM

@Zest4Quest: I agree with what @weberse has posted.  For an article on resolving overrides see Resolving Objects by Using Overrides.

In general, the factory pattern addresses the issue you are mentioning but I do understand your concern about the seemingly unending proliferation of factories this might cause.  I think part of the reason might be the example -- it's a little contrived so it's hard to tell the best design.

name and age sound like Value Objects whereas IComponent sounds like a service.  Or put another way: name and age are part of the application data which is not known at design time whereas IComponent is one of a known set of services.  If that is the case it might make sense to inject IComponent but have name and age be part of method data.

For example if you had a class Authenticator it might take constructor parameters of type ILogger and IAuthenticationProvider -- these would be injected services.  But you wouldn't inject username and password, you would just pass those into a method call such as Authenticate(username, password).  (Well, you would probably have a more generic method signature to account for different authentication schemes besides username/password but you get the idea.  :) )
Not to say that there are not any scenarios for using overrides, just some thoughts.

Randy Levy
Enterprise Library support engineer 

Jan 14, 2012 at 6:57 AM

Hi Randy,

 Thank you very much for your input..That's exactly the situation I was wondering about..A constructor injection which needed a Known Service and also some value type values that i had to associate with the object that will be created which would uniquely identify the instance created..For eg: an Employee class which needed a LoggingService but also an int employeeID value that would be used to identify the object created. If i use a method to associate the values it doesn't seem appropriate (what if the user forgets to call the Method which would set the ID )? Also, it becomes a 2 step process. I guess overriding would be the best option in this case...

Thanks once again...