在这种情况下,我怎么不使用DependencyResolver.Current.GetService(...)

Dib*_*Dib 13 c# dependency-injection anti-patterns ninject service-locator

按照我在这个线程中给出的建议[ Ninject UOW模式,用户通过身份验证后的新ConnectionString我现在明白我不应该使用以下行...

    var applicationConfiguration =
            (IApplicationConfiguration)
                DependencyResolver.Current.GetService(typeof(IApplicationConfiguration));
Run Code Online (Sandbox Code Playgroud)

......作为服务定位器是一种反模式.

但是在以下过程的情况下,如何实例化实现" IApplicationConfiguration "的具体对象,以便我可以使用该对象获取未知用户角色名称,或者使用它来分配我的原则的" ApplicationConfiguration "属性?

Global.asax中

public class MvcApplication : NinjectHttpApplication
{
    /// <summary>
    /// Handles the PostAuthenticateRequest event of the Application control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        String[] roles;
        var applicationConfiguration =
            (IApplicationConfiguration)
                DependencyResolver.Current.GetService(typeof(IApplicationConfiguration));
        var identity = HttpContext.Current.User.Identity;
        if (Request.IsAuthenticated)
        {
            roles = Roles.GetRolesForUser(identity.Name);
        }
        else
        {
            roles = new[] { applicationConfiguration.UnknownUserRoleName };
        }
        var webIdentity = new WebIdentity(identity, roles);
        var principal = new WebsitePrincipal(webIdentity)
        {
            ApplicationConfiguration = applicationConfiguration
        };

        HttpContext.Current.User = principal;
    }
    .
    .
    .
}
Run Code Online (Sandbox Code Playgroud)

分辨率映射代码

    public class ApplicationConfigurationContractMapping : NinjectModule
{
    public override void Load()
    {
        Bind<IApplicationConfiguration>()
            .To<ApplicationConfiguration>();
    }
}
Run Code Online (Sandbox Code Playgroud)

ApplicationConfiguration

public class ApplicationConfiguration : IApplicationConfiguration
{
    .
    .
    .
    .
}
Run Code Online (Sandbox Code Playgroud)

我使用Ninject作为我的依赖注入框架.任何建议赞赏.

编辑:完整的代码可以在这里看到:https: //github.com/dibley1973/Dibware.Template.Presentation.Web

Ste*_*ven 14

您无法阻止在您的DI容器中调用DI容器或对其进行抽象Application_PostAuthenticateRequest,但这不应该是一个问题,因为这Application_PostAuthenticateRequest可以被视为您的组合根的一部分.换句话说:你必须在某个地方解决它.

但是,在您的情况下,问题是此方法包含大量代码,而真正的问题是您缺少抽象.要解决此问题,请将此方法的所有逻辑提取到新类中,并将其隐藏在抽象之后.剩下的是以下代码:

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
   var provider = (IPostAuthenticateRequestProvider)
       DependencyResolver.Current.GetService(typeof(IPostAuthenticateRequestProvider));

   provider.ApplyPrincipleToCurrentRequest();
}
Run Code Online (Sandbox Code Playgroud)

代码可以由您的DI容器构建,并具有以下签名:

public class MvcPostAuthenticateRequestProvider : IPostAuthenticateRequestProvider
{
    private readonly IApplicationConfiguration configuration;

    public MvcPostAuthenticateRequestProvider(IApplicationConfiguration configuration)
    {
        this.configuration = configuration;
    }

    public void ApplyPrincipleToCurrentRequest()
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这很不错,而且看起来又漂亮又整洁。谢谢 (2认同)