Harsh Shah
Harsh Shah

Reputation: 678

Inject a string property in a class using Ninject

One of my interfaces has a string property that will depend on where the interface is being used. I want to avoid hardcoding the property every time the object is created. I can set the property in constructor, but the object is injected using a factory. The interface as follows:

public interface IObjectStore
{
    string StorageTableName { get; set;}

    void UpdateObjectStore(string key, string value);

    string ReadObjectStore(string key);
}

Which is used in a service

public class CategoryService<T> : ICategoryService<T> where T : Company
{
    private readonly IObjectStore objectStore;

    public CategoryService(IObjectStore objStore)
    {
        this.objectStore = objStore;
        objectStore.StorageTableName = "CategoryTable"; // I want to avoid this hard coding
    }
    ...
}

The service is created using service factory (Ninject.Extensions.Factory)

 public interface IServiceFactory
{
    ICategoryService<T> CreateCategoryService<T>() where T : class;
}

Which is then injected using Ninject at the controller level. Here are my bindings

bool storeInNoSql = true;
kernel.Bind<IServiceFactory>().ToFactory().InSingletonScope();
kernel.Bind<ICategoryService<Article>>().To<CategoryService<Article>>();
kernel.Bind<IObjectStore>().ToMethod(ctx => storeInNoSql ? ctx.Kernel.Get<ObjectStore>() : null);

So the question is: how do i tell Ninject to set the property StorageTableName to "CategoryTable" everytime the object is injected into CategoryService and to "ArticleTable" everytime it is inserted into ArticleService?

Upvotes: 3

Views: 1667

Answers (1)

sQuir3l
sQuir3l

Reputation: 1383

I think this is what you are looking for.
It's just a very small sample project I just did, but this should solve your problem.

public class Ninject_34091099
{
    public static void Run()
    {
        using (IKernel kernel = new StandardKernel())
        {
            kernel.Bind<IInterface<Generic1>>()
                  .To<Class<Generic1>>()
                  .WithConstructorArgument("name", "STRING ONE");

            kernel.Bind<IInterface<Generic2>>()
                .To<Class<Generic2>>()
                .WithConstructorArgument("name", "The other string");

            kernel.Bind<IServiceFactory>().ToFactory().InSingletonScope();

            var factory = kernel.Get<IServiceFactory>();
            var c1 = factory.CreateInterface<Generic1>();
            var c2 = factory.CreateInterface<Generic2>();

            Console.WriteLine(c1.Name);
            Console.WriteLine(c2.Name);
        }

        Console.WriteLine("Done");
        Console.ReadLine();
    }
}

public interface IInterface<T> where T : class
{
    string Name { get; set; }
}

public class Generic1
{

}

public class Generic2
{

}

public class Class<T> : IInterface<T> where T : class
{
    public string Name { get; set; }

    public Class(string name)
    {
        Name = name;
    }
}

public interface IServiceFactory
{
    IInterface<T> CreateInterface<T>() where T : class;
}

Sorry that the names mean nothing :D
Hope it helps

Upvotes: 5

Related Questions