0
votes

I have ConverterTest class where I need to access ValidateTest class. I can't pass ValidateTest using constructor because ConverterTest is abstract class. If I introduce second constructor to bind ValidateTest I will get numerous problems in derived classes and many things will need to change. So I have tried to pass ValidateTest to ConverterTest using property injection(decorated with inject attribute) but that also do not work because ConverterTest is not created by Ninject and inject properties are ignored. So I decided to create Instance property directly in ValidateTest class and bind instance of itself. To get instance of ValidateTest in ConverterTest class I use kernel.Get<ValidateTest>().Instance. Everything works fine but is it good idea to use kernel.Get to access instance class? Is there any other solution?

public class ValidateTest
{

        private readonly ISettingsRepository _settingsRepository;

        [Inject]
        public ValidateTest Instance { get; set; }

        public ValidateTest(ISettingsRepository settingsRepository)
        {
            _settingsRepository = settingsRepository;            
        }
}

Binding

kernel.Bind<ISettingsRepository>().To<SettingsRepository>();
kernel.Bind<ValidateAbuse>().ToSelf().InSingletonScope();

Getting instance of ValidateTest using kernel.Get in abstract class where constructor binding is not possible and property binding is not working.

public abstract class ConverterTest
{

        public void Execute()
        {
          NinjectHelper.kernel.Get<ValidateTest>().Instance
        }
}
1
Isn't the whole point of a DI container to hold the instance for you, so you don't have to ever worry about whether your objects are singletons or not? - cHao
@cHao There are cases where you only want your object created once for all users (often in a website). The point of a DI container is to allow you to create the instance from an outside location. - Justin Pihony
Is that Instance supposed to be static? Why does ValidateTest appear to have a circular reference to another one? Have to say I can't make hear or tail of your question. The first paragraph is impenetrable for me. Can you perhaps re-ask a simpler question? Def +1 on @cHao - Ninject can manage instancing of something in the container but the natural way to do all this is to have no singletons, static things or magic Instance methods. If someone needs an X, they either request it via ctor injection (or Propery Setter Injection), or outside of proper DI, you can do a Kernel.Get - Ruben Bartelink
(But a Kernel.Get, when outside of a composition root is normally Service Location - in fact having more than one Get is not a good smell either way) - Ruben Bartelink
I rescind my advice to re-ask unless you're actually going to close dups. You are def thinking about it wrong wanting to have magic Instance accessors that you seem to want to use for undescribed purposes. - Ruben Bartelink

1 Answers

1
votes

Why not have your subclasses of ConverterTest set the ValidateTest either via an exposed property in ConverterTest or constructor's of their own?

public abstract class ConverterTest
{
     protected ValidateTest ValidateTest{get;set;}

     public void Execute()
     {
         ValidateTest.ValidateStuff();
     }
}

public class ConcreteConverter : ConverterTest
{
    [Inject]
    public ConcreteConverter(ValidateTest validateTest)
    {
        base.ValidateTest = validateTest;
    }
}

Or, I think that you could make the property public public ValidateTest ValidateTest{get;set;} and it should work for property injection if you add the appropriate attribute.

public abstract class ConverterTest
{
     [Inject]
     public ValidateTest ValidateTest{get;set;}

     public void Execute()
     {
         ValidateTest.ValidateStuff();
     }
}