Dismissile
Dismissile

Reputation: 33071

Ninject Factory Custom Instance Provider

I'm using the Ninject Factory Extension and creating a custom instance provider explained in the wiki:

class UseFirstArgumentAsNameInstanceProvider : StandardInstanceProvider
{
    protected override string GetName(System.Reflection.MethodInfo methodInfo, object[] arguments)
    {
        return (string)arguments[0];
    }

    protected override Parameters.ConstructorArgument[] GetConstructorArguments(System.Reflection.MethodInfo methodInfo, object[] arguments)
    {
        return base.GetConstructorArguments(methodInfo, arguments).Skip(1).ToArray();
    }
}

I've defined the following factory interface:

interface IFooFactory
{
    IFoo NewFoo(string template);
}

I've created the following bindings:

kernel.Bind<IFooFactory>().ToFactory(() => new UseFirstArgumentAsNameInstanceProvider());
kernel.Bind<IFoo>().To<FooBar>().Named("Foo");

Now when I call the following I will get an instance of FooBar:

var foobar = fooFactory.NewFoo("Foo");

This all works great. What I would like however is something a little more like this:

interface IFooTemplateRepository
{
     Template GetTemplate(string template);
}

I have a repository that will bring back a template based on the name ("Foo") and I want to pass the template as a constructor argument.

public class FooBar
{
    public FooBar(Template template)
    {
    }
}

Is this possible? I'm not sure what should have the dependency on ITemplateRepository.

Upvotes: 2

Views: 2563

Answers (1)

Remo Gloor
Remo Gloor

Reputation: 32725

Don't use the IoC container to create instances of entities. This is business logic and therefore it does not belong in the composition root. The correct way to handle this is to use the ORM directly (e.g. with the repository pattern you are using).

var template = this.templateRepository.Get("SomeTemplate");
var fooBar = this.fooBarFactory.CreateFooBar(template);

Upvotes: 1

Related Questions