4

This is my first try using DI, I've chosen ninject for it's reportedly easy learning curve, and have this question.

I'm creating objects like this:

var registrants = JsonConvert.DeserializeObject<List<Registrant>>(input);

I currently have this constructor for Registrant

[Inject]
public Registrant(IMemberRepository memberRepository)
{
    _memberRepository = memberRepository;
}

What is the best way to have the repository dependency be injected into the deserialized object(s) using Ninject?

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Myster
  • 17,704
  • 13
  • 64
  • 93

2 Answers2

6

You can't use constructor injection with objects that are not created by Ninject (e.g. deserialized objects). But you can use property injection. Just call kernel.Inject(obj)

One question that remains is why you want to inject those objects. Normally, you don't want to use depedency injection on data container objects. In a proper design they don't have any dependency on services. The operations that need to be done on the services are done by the owner of the data container objects. I recommend to consider a refactoring of your design.

Remo Gloor
  • 32,665
  • 4
  • 68
  • 98
  • 2
    +1 Damn, just re-read the question -- this is clearly the correct answer! I started off wanting to explain that having an [Inject] attribute and expecting magic isnt going to work and then got sidetracked in setting up the example code and seeing the asp.net tag on the question. – Ruben Bartelink Feb 14 '11 at 12:59
  • 1
    Thanks, I thought that may be the story, which is why the question was very open ended :-) I think I'll take your refactoring advice also – Myster Feb 14 '11 at 20:00
1

Assuming you're using Ninject V2, and you're using it in the context of an ASP.NET app, you should be using Ninject.Web to do the hookups.

Then you set up a Global class with the Factory Method support hooked in:

public class Global : NinjectHttpApplication
{
    protected override Ninject.IKernel CreateKernel()
    {
        var kernel = new StandardKernel( new Module() );
        kernel.Components.Add( new FuncModule( ) );
        return kernel;
    }
}

that registers the module that will Bind IMemberRepository to something:

    public class Module : NinjectModule
    {
        public override void Load()
        {
            Bind<IMemberRepository>().To<MemberRepository>();
        }
    }

and the page wires up like this:

public class ThePage : PageBase
{
    readonly Func<Registrant> _createRegistrant;

    public ThePage( Func<Registrant> createRegistrant )
    {
        _createRegistrant = createRegistrant;
    }

    private void OnCreateRegistrant()
    {
        var newRegistrant = _createRegistrant();
    }
}

NB not 100% sure if constructor injection is supported for Web Forms pages or wheter the above needs to drop to property injection... anyone?

(assuming the classes you have are as follows:)

public class MemberRepository : IMemberRepository
{
}

public interface IMemberRepository
{
}

public class Registrant
{
    private readonly IMemberRepository _memberRepository;
    public Registrant( IMemberRepository memberRepository )
    {
        _memberRepository = memberRepository;
    }
}
Community
  • 1
  • 1
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
  • @Myster: As noted in my comment on @Remo's answer, I missed the fact that you want to do this on objects that you're deserializing. Thus this example wont be much use to you as you're trying to influence over creation of objects elsewhere, not manage your creation thereof succinctly. Even if it were, it's architecturally debatable... – Ruben Bartelink Feb 14 '11 at 13:08
  • Thanks @Ruben, as you note you're answering a different question, as a matter of interest... I have all that code except for the `ThePage` class, what's the idea there? The ability to inject 'how' the registrants are created? – Myster Feb 14 '11 at 19:57
  • @Myster: 1. that you can feed stuff into the asp.net pages aytomatically by deriving from `Ninject.PageBase` 2. that the module I linked to will auto-generate a factory which will generate an object *and do injection on its dependencies*. without you having to tell it how – Ruben Bartelink Feb 15 '11 at 05:43