1
votes

I have a legacy application that I want to modify to use Ninject to reduce coupling.

I have a number of classes in the data layer that share a base type:

public abstract class BaseData { }

public class Child1Data : BaseData { }

public class Child2Data : BaseData { }

I also have a number of classes that use/manage these:

public abstract class BaseManager { }
public class Child1Manager : BaseManager { }
public class Child2Manager : BaseManager { }

I have to create a function that maps one to another:

BaseManager GetManager(BaseData dataObject)
{
    //Want to use Ninject to do this
    if (dataObject is Child1Data)
       return new Child1Manager(dataObject);
    //...etc
}

I created a NinjectModule with the following bindings:

Bind<BaseManager>().To<Child1Manager>.Named(typeof(Child1Data).FullName);

Then in my GetManager() function I can do:

BaseManager GetManager(BaseData dataObject)
{
    return ServiceLocator.Get<BaseManager>(dataObject.GetType().FullName);
}

Is there an easier and more proper way to bind service to specific type?

I can modify children of BaseManager, but unfortunately I have to preserve BaseData and the signature of GetManager() function.

Thank you in advance for your ideas and suggestions. This is my first exposure to Ninject and dependency injection.

1

1 Answers

0
votes

You can achieve this with a factory:

public interface IManagerFactory
{
    BaseManager GetManager(BaseData dataObject);
}


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

Bind<IManagerFactory>().ToFactory(() => new UseFirstArgumentTypeAsNameInstanceProvider());
Bind<BaseManager>().To<Child1Manager>().Named(typeof(Child1Data).FullName);
Bind<BaseManager>().To<Child2Manager>().Named(typeof(Child2Data).FullName);

Then inject your IManagerFactory where you want.