0

我试图找出如何将 StructrueMap 容器传递给我编写的从另一个(MS-Class)继承的类。

namespace TheNamespace
{
  public class DatabaseIssuerNameRegistry : ValidatingIssuerNameRegistry
  {
    /* **This can't be done**
    public DatabaseIssuerNameRegistry(IPortalTenantManager portalTenantManager)
    {
        _someField= portalTenantManager;
    }*/


    protected override bool IsThumbprintValid(string thumbprint, string issuer)
    {
       //How does it work ???????????

       var portalTenantManager = container.GetInstance<IPortalTenantManager>();
      //Do something with the portalTenantManager
    }
}

我需要 portalTenantManager 是我在 Global.asax 的容器中定义的实例。

我的 Global Assax 设置了以下内容:

protected void Application_Start()
{
 var container = new Container();
 container.Configure(x =>
            { ....
              ....
             x.For<IPortalTenantManager>().Use<PortalTenantManager>();
             });

...

...
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory(container));
...
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapApiControllerFactory(container);
...
    }

编辑: 由于@NightOwl888 的评论,我将进一步解释这个类的作用。(希望能解释一下为什么我的手被绑住了)

我的应用程序能够使用 Azure Active Directory 对用户进行身份验证,并且支持多租户。在身份验证管道中,我可以将验证端点存储在我的数据库中,而不是 web.config 文件中的默认方式。请参阅 MSDNthis,它实际上正在解释我在做什么。

所以我在标签issuerNameRegistry下的 web.config 中注册了我的课程。在验证管道的某个时刻,我的类被实例化,并且被覆盖的方法IsThumbprintValid被调用。问题是在issuerNameRegistry中注册的类需要一个无参数的构造函数(就是它!受约束的构造!),因此我无法创建一个可以解决我的问题的构造函数。

谢谢你的帮助

4

1 回答 1

1

事实证明,这个问题之前已经在 MSDN 上提出过,Travis Spencer 在 2 个不同的帖子中提供了答案。

在我的经验中,典型的做法是拥有一个容器并在整个服务或 Web 端使用该容器。在服务或 Web 应用程序启动时,您可以创建容器、注册依赖项、新建 SecurityTokenServiceConfiguration 类的实例、解析依赖项、使用它来生成 SecurityTokenService 对象并托管它。

在第一个测试版之后,我们真正推动了 DI 支持。我们在 beta 2 中有一个小钩子。您现在可以创建一个自定义 SecurityTokenServiceConfiguration 类来覆盖虚拟 CreateSecurityTokenService 方法。Microsoft 的 SecurityTokenServiceConfiguration 中的实现是 Activator.CreateInstance;你的可以做 IoC。这可以包括对 IssuerNameRegistiry 的解析。可能是这样的:

RequestSecurityTokenResponse Issue(IClaimsPrincipal principal, RequestSecurityToken request)
{
    SecurityTokenServiceConfiguration config = new MyGoodSecurityTokenServiceConfiguration();
    SecurityTokenService sts = config.CreateSecurityTokenService();
    RequestSecurityTokenResponse rstr = sts.Issue(principal, request);

    return rstr;
}

public class MyGoodSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration
{
    public override SecurityTokenService CreateSecurityTokenService()
    {
        IssuerNameRegistry = IoC.Resolve<IssuerNameRegistry>();
    
        var sts = IoC.Reslove<SecurityTokenService>();

        return sts;
    }
}

当然,这意味着您需要创建 DI 容器的静态实例,以便您的SecurityTokenServiceConfiguration类可以访问它。就个人而言,我不喜欢这个想法,因为它使您的 DI 容器可以在整个应用程序中访问,这可能导致 DI 容器被滥用为服务定位器。

理想情况下,任何 DI 友好的框架中都有一种方法可以将容器传递到抽象工厂,以解决服务依赖关系。但是,由于我不熟悉 WIF,因此不清楚是否可以这样做 - 也许该Issue方法所在的类可以添加一个构造函数?诀窍是不断向上走,直到找到框架中的第一个位置,在那里您可以干预并在那里进行所有 DI 配置。

于 2015-12-31T09:12:34.807 回答