0

Let's say I have the following model:

public class Dojo
{
    public int DojoId {get;set;}
    public DojoProperty PropOne{get;protected set;}
    public DojoProperty PropTwo{ get;protected set; }
    public virtual ICollection<ISamurai> Warriors { get; set; }
    private IDojoService _dojoService;
    public Dojo(IDojoService dojoService)
    {
        _dojoService = dojoService;
    }
}

I'm using the latest ninject for DI and want to have a factory method and also implement the latest version of Entity Framework for ORM so I refactor the class as follows:

public class Dojo
{
    public int DojoId {get;set;}
    public DojoProperty PropOne{get;protected set;}
    public DojoProperty PropTwo{ get;protected set; }
    public virtual ICollection<ISamurai> Warriors { get; set; }
    private IDojoService _dojoService;
    private Dojo(IDojoService dojoService)
    {
        _dojoService = dojoService;
    }
    public static Dojo Create(IDojoService dojoService, IDojoConfig dojoConfig)
    {
        return new Dojo(dojoService) {PropOne = dojoConfig.PropOne, PropTwo = dojoConfig.PropTwo};
    }
}

My question is, how do I get Entity Framework to use the IoC container to inject the IDojoService when I retrieve the Dojo from the database i.e.:

context.Dojos.Find(dojoId);
ChrisT
  • 157
  • 9
  • 3
    My advice is: don't do constructor injection (nor property injection) in your entities: https://stackoverflow.com/questions/28715966/entity-framework-object-materialization-and-dependency-injection – Steven Mar 10 '15 at 14:39
  • Many thanks for your comment @Steven . If you would take a look at my answer and see if it is a better approach than the one from the question. If you have a better answer I'll happily accept over mine, especially if I've missed some key details – ChrisT Mar 10 '15 at 22:34

1 Answers1

0

So Steven's comment led me to do lots of useful reading, particularly this article of his (I assume?) https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91

At first I misinterpreted his approach, the original answer is below.

My new answer based on his most recent comment is:
Usage first:

    public void AddWarrior(int dojoId, ISamurai warrior)
    {
         var command = new AddWarriorCommand {DojoId = dojoId, Warrior = warrior};
         handler.Handle(command);
    }

More depth on the AddWarriorCommandHandler:

public class AddWarriorCommandHandler : ICommandHandler<AddWarriorCommand>
{
    //ommitted ctor bringing in dependencies (e.g. Repository)
    public void Handle(AddWarriorCommand command)
    {
            var dojo = context.Dojos.Find(command.dojoId);
            dojo.Warriors.Add(command.Warrior);
            context.SaveChanges();
    }
}

The new model:

public class Dojo
{
    public int DojoId { get; set;}
    public DojoProperty PropOne { get; protected set;}
    public DojoProperty PropTwo{ get; protected set; }
    public virtual ICollection<ISamurai> Warriors { get; set; }

    private Dojo(){}

    public static Dojo Create(IDojoConfig dojoConfig)
    {
        return new Dojo() {PropOne = dojoConfig.PropOne, PropTwo = dojoConfig.PropTwo};
    }
}

Old answer for posterity: This led me to interpret the following approach which helps prevent the anaemic domain models I was trying to avoid, keeps the IoC container and ORM happy and in fact improves overall SOLIDness, testability and the other benefits outlined in his article.

public class Dojo
{
    public int DojoId { get; set;}
    public DojoProperty PropOne { get; protected set;}
    public DojoProperty PropTwo{ get; protected set; }
    public virtual ICollection<ISamurai> Warriors { get; set; }

    private Dojo(){}

    public static Dojo Create(IDojoConfig dojoConfig)
    {
        return new Dojo() {PropOne = dojoConfig.PropOne, PropTwo = dojoConfig.PropTwo};
    }

    public void AddWarrior(ICommandHandler<AddWarriorCommand> handler, ISamurai warrior)
    {
         var command = new AddWarriorCommand {Warrior = warrior};
         handler.Handle(command);
    }
}

And then the usage:

var dojo = context.Dojos.Find(dojoId);
dojo.AddWarior(handler, new Warrior());

With the AddWarriorCommand : ICommand and ICommandHandler defined as per the article and the latter injected into the dependent class with ninject

ChrisT
  • 157
  • 9
  • This is an interesting approach, but not a common one for people who use command handlers in conjunction with DDD. Instead more usual is to invert the dependency and let the command handler call the methods on the warrior. In other words: presentation layer executes a command and the command handler loads one or multiple entities and calls the domain method on them. ps. Yes, that article is mine. – Steven Mar 11 '15 at 08:11
  • Many thanks @Steven I've updated based on your latest comment. I *think* I get it now. Your guidance has been very much appreciated – ChrisT Mar 11 '15 at 13:26