2016-09-16 4 views
2

Мой проект использует ASP.NET MVC и Ninject для привязки абстрактных интерфейсов к конкретным реализациям, поэтому мой сайт Controllers может извлекать данные. Однако теперь я хочу добавить возможность получения одного и того же набора данных из другого места. Для этого потребуется другая реализация абстрактного интерфейса, который я использую, но все вызовы метода одинаковы. Я все еще хочу использовать Ninject, но я не хочу просто копировать интерфейс, который у меня уже есть, и называть его чем-то другим.Как использовать Ninject & MVC с несколькими реализациями одного интерфейса?

EDIT 1: Я только что понял, что я никогда не задавал вопрос. Как сообщить Ninject и/или фабрикам ASP.NET Controller для использования одной реализации абстрактного класса над другой, основанной исключительно на строке запроса?

Вот пример того, что я говорю о:

// Global.asax.cs 

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     // Using Ninject resolver 
     NinjectResolver.SetResolver(new NinjectResolver()); 
    } 
} 

// NinjectResolver.cs 

public class NinjectResolver : IDependencyResolver 
{ 
    private IKernel kernel; 

    public NinjectResolver() 
    { 
     kernel = new StandardKernel(); 
     AddBindings(); 
    } 

    public void AddBindings() 
    { 
     // I don't know what to do here: 

     //kernel.Bind<IFooModel>().To<FooModelImplementation>(); 
     //kernel.Bind<IFooModel>().To<FooModelImplementation2>(); 
    } 
} 

Реализация интерфейса:

// FooModel.cs 

public interface IFooModel 
{ 
    FooData GetData(int dataID); 
} 

public class FooData 
{ 
    public string Field1 {get; set;} 
    public string Field2 {get; set;} 
    public string Field3 {get; set;} 
    // ... 
    public FooData() 
    { } 
} 

public class FooModelImplementation : IFooModel 
{ 
    public FooModelImplementation() 
    { } 

    public FooData GetData(int dataID) 
    { 
     // Get data... 
    } 
} 

public class FooModelImplementation2 : IFooModel 
{ 
    public FooModelImplementation2() 
    { } 

    public FooData GetData(int dataID) 
    { 
     // Get data from source 2... 
    } 
} 

и моя Controller:

// FooController.cs 

public FooController : BaseController 
{ 
    private IFooModel mFooModel; 

    public FooController(IFooModel fooModel) 
    { 
     mFooModel = fooModel; 
    } 

    // http://www.example.com/Foo?dataID=1&location=2 
    public ViewResult FooView(int dataID) 
    { 
     // Here I want the mFooModel to be an instance of FooModelImplementation2 
     // because "location" is 2. How do I do this? 
     FooData data = mFooModel.GetData(dataID); 
     FooViewModel viewModel = new FooViewModel 
     { 
      Field1 = data.Field1; 
      Field2 = data.Field2; 
     }; 
     return View(viewModel); 
    } 
} 

public class FooViewModel 
{ 
    public string Field1 {get; set;} 
    public string Field2 {get; set;} 

    public FooViewModel() 
    { } 
} 
+2

Эта документация должна поставить вас на правильный путь: https://github.com/ninject/Ninject/wiki/Contextual-Binding –

+0

проверить это https://github.com/ninject/Ninject/wiki/Multi-injection –

ответ

1

Используйте расширение завода (https://github.com/ninject/Ninject.Extensions.Factory/wiki/Factory-interface%3A-Referencing-Named-Bindings), чтобы ввести завод в контроллер вместо модели.

Завод может использоваться для получения именованных экземпляров. Создайте два именованных привязки и выберите подходящий в контроллере.

+0

Привет @Remo. Как вы думаете, вы могли бы взглянуть на этот вопрос? http://stackoverflow.com/questions/40198294/how-to-configure-ninject-so-that-it-creates-a-single-instance-per-controller?noredirect=1#comment67673663_40198294 – eddy