Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor Injection with TinyIoC

I have just changed from Ninject to TinyIoC for dependency injection and I'm having trouble with constructor injection.

I have managed to simplify it down to this snippet:

public interface IBar { } 

public class Foo
{
    public Foo(IBar bar) { }
}

public class Bar : IBar
{
    public Bar(string value) { }
}

class Program
{
    static void Main(string[] args)
    {
        var container = TinyIoCContainer.Current;

        string value = "test";
        container.Register<IBar, Bar>().UsingConstructor(() => new Bar(value));

        var foo = container.Resolve<Foo>();
        Console.WriteLine(foo.GetType());
    }
}

which causes a TinyIoCResolutionException to be thrown with:

"Unable to resolve type: TinyIoCTestApp.Foo"

and inside that exception is a chain of inner exceptions:

"Unable to resolve type: TinyIoCTestApp.Bar"
"Unable to resolve type: System.String"
"Unable to resolve type: System.Char[]"
"Value cannot be null.\r\nParameter name: key"

Is there something wrong with the way I'm using the constructor injection? I realize I could call

container.Register<IBar, Bar>(new Bar(value));

and that does indeed work, however the result is a global instance of Bar which is not what I'm after.

Any ideas?

like image 592
AndrewG Avatar asked Feb 08 '12 23:02

AndrewG


People also ask

What is constructor injection?

Typically, a class constructor is invoked when instantiating an object, and any values that the object needs are passed as arguments to the constructor. This is an example of dependency injection, and specifically is known as constructor injection.

What is tinyioc and how does it work?

It typically uses a container that holds a list of registrations and mappings between interfaces and abstract types, and the concrete types that implement or extend these types. TinyIoC is a lightweight container that features superior performance on mobile platforms when compared to the majority of the well-known containers.

Why does tinyioc create a new instance of the registered type?

After registering a type using a concrete class registration, the default behavior for TinyIoC is to create a new instance of the registered type each time the type is resolved, or when the dependency mechanism injects instances into other classes. In this scenario, the container doesn't hold a reference to the resolved object.

What are some examples of tinyioc?

Example usage of TinyIoC - the first with constructor injection, the second with property injection. // This is the interface for my aspect - the dependency for my classes. // And here is an implementation. return "Hello World!";


1 Answers

I'm not familiar with TinyIOC, but I think I can answer your question.

The UsingConstructor registers a lambda that points at a constructor (the ctor(string)) that TinyIOC will use to do automatic constructor injection into. TinyIOC will analyse the constructor arguments, finds an argument of type System.String and tries to resolve that type. Since you haven't registered System.String explicitly (which you shouldn't btw), resolving IBar (and thus Foo) fails.

The incorrect assumption you made is that TinyIOC will execute your () => new Bar(value)) lambda, which it will not. If you look at the UsingConstructor method you will propable see that it takes an Expression<Func<T>> instead of a Func<T>.

The thing you want, is to register a factory delegate that does the creation. I expect TinyIOC to contain a method for this. It might look something like this:

container.Register<IBar>(() => new Bar(value));
like image 197
Steven Avatar answered Oct 03 '22 19:10

Steven