使用城堡温莎的ASP.NET MVC中的条件依赖项解析 [英] Conditional dependency resolution in ASP.NET MVC using castle windsor

查看:49
本文介绍了使用城堡温莎的ASP.NET MVC中的条件依赖项解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我们的代码中解决这种情况,我需要在运行时根据特定条件(例如是否存在某些查询字符串值)来解决依赖性。



让我说我有一个控制器AuthenticationController,并且我有两种身份验证服务。

 公共类AuthenticationController 
{
私有只读IAuthenticationService authenticationService;

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

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

公共接口IAuthenticationService
{
bool AuthenticatUser(string userName,string password);
}

公共类ProviderBasedAuthenticationService:IAuthenticationService
{
public bool AuthenticatUser(string userName,string password)
{
//使用提供者;
返回true;
}
}


公共类ThirdPartyAuthenticationService:IAuthenticationService
{
public bool AuthenticatUser(string userName,string password)
{
//使用第三方进行身份验证;
返回true;
}
}

我已经使用温莎城堡实现了IoC和DI。 / p>

我正在Castle容器中同时注册ProviderBasedAuthenticationService和ThirdPartyAuthenticationService for IAuthenticationService。



当前Castle解析了首次注册的对象



我希望根据请求URL或路由数据中作为查询字符串一部分的某些值来解析IAuthenticationService的适当类型。



我发现可以使用Microsoft UnityContainer以某种方式完成此操作,但是我不确定如何在温莎城堡中实现这一目标。 (我现在不能将容器更改为Microsoft UnityContainer。)



如果有人可以在此方面为我提供帮助或提供一些指导,将不胜感激。

>

谢谢,问候
Chetan Ranpariya

解决方案

您可以做到这是一种工厂方法。例如:

 私有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)=>此。 AuthenticationServiceFactory(k)));

返回容器;
}

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

和2个单元测试来证明解决方案

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

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

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

[事实]
public void Resolve_WithTheRequiredQueryString_ReturnsThirdPartyAuthenticationService()
{
var container = this.ContainerFactory();
HttpContext.Current =新的HttpContext(
新的HttpRequest(, http:// localhost, SomeKey = Value),
新的HttpResponse(null));

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

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


I am trying to solve this case in our code where I need to resolve the dependency at runtime based on a specific condition, such as if certain query string value exist or not.

Let say I have a controller AuthenticationController and I have authentication service having two flavours of it.

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;
    }
}

I have implemented IoC and DI using castle windsor.

I am registering both ProviderBasedAuthenticationService and ThirdPartyAuthenticationService for IAuthenticationService in Castle container.

Currently Castle resolves object of the first registered type when resolving IAuthenticationService.

I wish to resolve appropriate type of IAuthenticationService depending on certain value coming as part of query string in the request URL or route data.

I found that this can be somehow done using Microsoft UnityContainer but I am not sure how to achieve this in Castle Windsor. (I can not change my container now to Microsoft UnityContainer).

It would be much appreciated if anyone can help me on this or provide some direction around this.

Thanks and regards, Chetan Ranpariya

解决方案

You can do this with a factory method. Here's an example:

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>();
}

And 2 unit tests to prove the solution

[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);
}

这篇关于使用城堡温莎的ASP.NET MVC中的条件依赖项解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆