views:

398

answers:

3

I'm trying to build my own inversion of control container. Right now I store the objects with their types in a dictionary and resolve a reference when asked. But I want to make it possible to resolve a reference or a new instance. I can create a new instance with the Activator class. But, what if the constructor of the object to resolve takes 1, 2 or any parameters?

For example, I want to be able to say something like:

Container.register<IFoo>(new Foo(Proxy));
Container.register<IBar>(new Boo(Proxy, DataThing));

and resolve it like

IFoo MyFoo = Resolver.resolve<IFoo>();
IBar MyBar = Resolver.resolve<IBar>();

where MyFoo gets instanciated with the given parameter Proxy and MyBar with Proxy and DataThing.

What does resolve have to do to make that happen?

A: 

Activator can create an instance of a class having constructors with parameters.

Have a look at this overload of CreateInstance method.

You can provide a custom binder to search for matching constructor manually.

In your case resolve method should return reference to an instance of registered class (new Boo(Proxy, DataThing) in your example)

aku
Why a reference and not a new instance? won't that mean that if I resolve this Boo in 6 places, all 6 are 1?
Sorskoot
Why a new instance? typically "resolve" method would return existing item. If you need a new instance indicate it explicitly i.e. create "create" method or add an argument. How are you going to distinguish between "get new" and "get existing" scenarios?
aku
I thought of explicity telling it to become a singleton or something like that when registering: Container.register<IFoo>(new Foo(Proxy), true); would create a "get existing" scenario.
Sorskoot
Btw, I overlooked that overload of CreateInstance. I think I need that one. Do you know how if it is possible to tell what parameters where used in the construction of an object?
Sorskoot
If you want to analyze constructor you can use reflection. Out of curiosity why do you need to roll out home-made IoC container when there's plenty of existing solutions?
aku
Usually IoC frameworks provide attributes to add some guidance on parameter values selection. By default IoC container simply search for best fitting constructor based on parameters passed to resolve method
aku
I need it as small as possible for use in a Silverlight app, with only the features I need. And I love to learn how it works.
Sorskoot
Anyway have a look at http://www.ninject.org/ - it supports Silverlight
aku
Thanks, I'll have a look at that one.
Sorskoot
+1  A: 

I decided to split it in to methods. A Resolve, that gives back the instance stored in the container. And a Create that instanciate a new instance.

something like:

 public T Create<T>()
         {
             if (registeredTypes.ContainsKey(typeof(T)))
                 return (T)Activator.CreateInstance(registeredTypes[typeof(T)].
                                                                       GetType());
             else
                 throw new DependencyResolverException("Can't
                                       create type. Type " + typeof(T) + "
                                                           not found.");
         }
Sorskoot
+2  A: 

Checkout http://funq.codeplex.com. This is a very tiny Container that uses lambda expressions to define the function to resolve. Handles multiple parameters.

Matthew