Использование Ninject для настройки сервисов - PullRequest
3 голосов
/ 03 августа 2011

Во-первых, я новичок в Ninject, но хотя этот вопрос касается Ninject, похоже, он относится к DI в целом.

Я думаю, что мне здесь чего-то не хватает. Предлагаемые решения пока кажутся ужасно сложными.

У меня было что-то вроде этого:

public class MyController : Controller
{
    private IMyService _Service;

    public MyController()
        :this(null)
    { }

    public MyController(IMyService service)
    {
        _Service = service ?? new MyService(ModelState);
    }
}

public IMyService
{}

public class MyService : IMyService
{
    private ModelStateDictionary _Model;

    public MyService(ModelStateDictionary model)
    {
        _Model = model;
    }
}

И поэтому я подумал, что поеду на Ninject И придумал это:

public class MyController : Controller
{
    private IMyService _Service;

    public MyController()
        :this(null)
    {
        _Service = Locator.Kernel.Get<IMyService>(new Ninject.Parameters.ConstructorArgument("model", ModelState));
    }
}

public class MyServiceModule : NinjectModule
{
    public override Load()
    {
        Bind<IMyService>().To<MyService>(); //here
    }
}

Мне кажется, что я должен быть в состоянии изменить бит, где он связывается (отмечен здесь), чтобы он знал в этот момент для получения состояния модели, а не когда мне нужен экземпляр в конструкторе, который требует предварительных знаний конкретного класса обслуживания.

Я бесполезно беспокоюсь или есть лучший способ сделать это?

Simon

1 Ответ

0 голосов
/ 03 августа 2011

Неужели MyService действительно нужно построить ModelStateDictionary?

Я бы посмотрел в сторону его рефакторинга, чтобы я передавал ModelStateDictionary в метод, который я вызывал, а не требовал его для построения класса Service.

Если такой рефакторинг нецелесообразен, вы, вероятно, захотите добавить слой абстракции поверх ModelStateDictionary

public interface IModelStateProvider {
    ModelStateDictionary GetModelState();
}

И создайте реализацию этого интерфейса, которая может получить текущий контекст ModelStateDictionary, затем установите привязку этого интерфейса и измените класс обслуживания, чтобы он принимался в конструкторе:

public class MyService : IMyService
{
    private ModelStateDictionary _Model;

    public MyService(IModelStateProvider modelStateProvider)
    {
        _Model = modelStateProvider.GetModelState();
    }
}
...