2

Я пытаюсь решить этот случай в нашем коде, где мне нужно разрешить зависимость во время выполнения на основе определенного условия, например, если существует определенное значение строки запроса.Условное разрешение зависимостей в ASP.NET MVC с использованием windsor замка

Позвольте сказать, что у меня есть контроллер AuthenticationController, и у меня есть служба аутентификации, имеющая два варианта.

public class AuthenticationController 
{ 
    private readonly IAuthenticationService authenticationService; 

    public AuthenticationController(IAuthenticationService authenticationService) 
    { 
     this.authenticationService = authenticationService; 
    } 

    public ActionResult LogOn(LogOnModel model) 
    { 
     var isAuthenticated = authenticationService.AuthenticatUser(model.UserName, model.Password); 
    } 
} 

public interface IAuthenticationService 
{ 
    bool AuthenticatUser(string userName, string password); 
} 

public class ProviderBasedAuthenticationService : IAuthenticationService 
{ 
    public bool AuthenticatUser(string userName, string password) 
    { 
     // Authentication using provider; 
     return true; 
    } 
} 


public class ThirdPartyAuthenticationService : IAuthenticationService 
{ 
    public bool AuthenticatUser(string userName, string password) 
    { 
     // Authentication using third party; 
     return true; 
    } 
} 

Я внедрил IoC и DI с помощью виндзора замка.

Я регистрирую службу ProviderBasedAuthenticationService и ThirdPartyAuthenticationService для IAuthenticationService в контейнере замка.

В настоящее время замок разрешает объект первого зарегистрированного типа при разрешении IAuthenticationService.

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

Я обнаружил, что это можно как-то сделать с помощью Microsoft UnityContainer, но я не уверен, как этого добиться в Castle Windsor. (Я не могу изменить свой контейнер сейчас в Microsoft UnityContainer).

Было бы очень признательно, если кто-нибудь может мне помочь в этом или обеспечить какое-то направление вокруг этого.

Спасибо и уважением, Четан Ranpariya

ответ

5

Вы можете сделать это с помощью фабричного метода. Вот пример:

private WindsorContainer ContainerFactory() 
{ 
    var container = new WindsorContainer(); 
    container.Register(
     Component.For<ProviderBasedAuthenticationService>() 
      .LifeStyle.Transient, 
     Component.For<ThirdPartyAuthenticationService>() 
      .LifeStyle.Transient, 
     Component.For<AuthenticationController>() 
      .LifeStyle.Transient, 
     Component.For<IAuthenticationService>() 
      .UsingFactoryMethod((k, c) => this.AuthenticationServiceFactory(k))); 

    return container; 
} 

private IAuthenticationService AuthenticationServiceFactory(IKernel kernel) 
{ 
    return HttpContext.Current != null && 
      HttpContext.Current.Request != null && 
      HttpContext.Current.Request.QueryString["SomeKey"] != null 
     ? (IAuthenticationService)kernel.Resolve<ThirdPartyAuthenticationService>() 
     : (IAuthenticationService)kernel.Resolve<ProviderBasedAuthenticationService>(); 
} 

И 2 юнит-тесты, чтобы доказать Решение

[Fact] 
public void Resolve_WithoutTheRequiredQueryString_ReturnsProviderBasedAuthenticationService() 
{ 
    var container = this.ContainerFactory(); 

    var result = container.Resolve<AuthenticationController>(); 

    Assert.IsType<ProviderBasedAuthenticationService>(result.authenticationService); 
} 

[Fact] 
public void Resolve_WithTheRequiredQueryString_ReturnsThirdPartyAuthenticationService() 
{ 
    var container = this.ContainerFactory(); 
    HttpContext.Current = new HttpContext(
     new HttpRequest("", "http://localhost", "SomeKey=Value"), 
     new HttpResponse(null)); 

    var result = container.Resolve<AuthenticationController>(); 

    Assert.IsType<ThirdPartyAuthenticationService>(result.authenticationService); 
} 
+1

Hi qujk, вы прибил его. Я как-то не мог думать о наличии отдельного метода фабрики, но я пытался это сделать, используя встроенный динамический метод. Подход, который вы предоставляете, должен непременно работать. Спасибо. - Четан Ранпария –