C# 如何使用Simple Injector在自定义ClaimsPrincipal中注入服务

C# 如何使用Simple Injector在自定义ClaimsPrincipal中注入服务,c#,asp.net-mvc,dependency-injection,adfs,simple-injector,C#,Asp.net Mvc,Dependency Injection,Adfs,Simple Injector,我正在从事一个ASP.NETMVC项目,该项目使用ADF进行身份验证,并使用SimpleInjector作为IoC容器。应用程序的服务层位于不同的项目中,服务在启动时注入控制器构造函数。其中一个服务是一个用户服务,我想用它从我的数据层获取用户信息等 我有一个自定义主体(继承自ClaimsPrincipal),我希望在其中使用此用户服务并存储用户信息。我面临的问题是,我不确定如何将用户服务“粘合”到自定义主体 我尝试在每次身份验证之后获取用户服务的一个实例,并将其注入到标识中,但我得到一个错误,即

我正在从事一个ASP.NETMVC项目,该项目使用ADF进行身份验证,并使用SimpleInjector作为IoC容器。应用程序的服务层位于不同的项目中,服务在启动时注入控制器构造函数。其中一个服务是一个用户服务,我想用它从我的数据层获取用户信息等

我有一个自定义主体(继承自ClaimsPrincipal),我希望在其中使用此用户服务并存储用户信息。我面临的问题是,我不确定如何将用户服务“粘合”到自定义主体

我尝试在每次身份验证之后获取用户服务的一个实例,并将其注入到标识中,但我得到一个错误,即容器不包含该服务的一个实例。我的代码如下:

应用程序启动()

InjectorConfig

public class InjectorConfig
{
    /// <summary>
    /// Create the IoC container and register all dependencies
    /// </summary>
    public static void RegisterDependencies(Container container)
    {
        // Create the IoC container
        //var container = new Container();

        // Get the assembly that houses the services
        var serviceAssembly = typeof (UserService).Assembly;

        // Interate through the assembly and find all the services 
        var registrations = (
            from type in serviceAssembly.GetExportedTypes()
            where type.Namespace == "MyApp.Services"
            where type.GetInterfaces().Any()
            select new
            {
                Service = type.GetInterfaces().Single(), 
                Implementation = type,
            });

        // Register each of the services
        foreach (var registration in registrations)
        {
            container.Register(registration.Service, registration.Implementation, Lifestyle.Transient);
        }

        // Verify the container and set the MVC dependency resolver
        container.Verify();
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }
}
我的用户服务(在不同的程序集中)

应用程序\u PostAuthenticateRequest()

这就是错误发生的地方。没有可用的实例

    protected void Application_PostAuthenticateRequest()
    {
        var currentUser = ClaimsPrincipal.Current.Identity;

        // This is where the error occurs. No instance available
        var userService = this._container.GetInstance<IUserService>();
        HttpContext.Current.User = new MyCustomPrincipal(currentUser, userService);
    }

我可以想出5个可能的原因来解释为什么会发生这种情况:

  • UserService类未实现IUserService
  • UserService类不位于命名空间“MyApp.Services”中
  • 这个类是内部的
  • 您不小心创建了第二个(空)容器
  • 在调用RegisterDependencies之前调用PostAuthentication方法

  • 您得到的错误到底是什么?你能发布完整的异常、消息和堆栈跟踪吗?嗨@Steven,谢谢回复。我已经用堆栈跟踪更新了这个问题。嗯,消息很清楚。你确定这是同一个容器吗?您可以在调试器中查看容器的注册。可能您的RegisterDependencies没有被调用,或者您在调用后创建了一个新容器。感谢您的帮助@Steven。我最终用
    var userService=dependencysolver.Current.GetService()解决了这个问题@Andrew如果这解决了问题,那么必须有第二个容器实例。你真的应该知道为什么会这样,因为这可能会带来更多的麻烦。
    
    public class MyCustomPrincipal : ClaimsPrincipal
    {
        private readonly IUserService _userService;
    
        public MyCustomPrincipal(IIdentity identity, IUserService userService)
            :base(identity)
        {
            this._userService = userService;
        }
    
        public override bool IsInRole(string role)
        {
            return this._userService.IsInRole(this.Identity.GetUserId(), role);
        }
    }
    
    public class UserService : IUserService
    {
        public bool IsInRole(string currentUserId, string roleName)
        {
            // Check roles here
            return true;
        }
    }
    
        protected void Application_PostAuthenticateRequest()
        {
            var currentUser = ClaimsPrincipal.Current.Identity;
    
            // This is where the error occurs. No instance available
            var userService = this._container.GetInstance<IUserService>();
            HttpContext.Current.User = new MyCustomPrincipal(currentUser, userService);
        }
    
    SimpleInjector.ActivationException was unhandled by user code
      HResult=-2146233088
      Message=No registration for type IUserService could be found.
      Source=SimpleInjector
      StackTrace:
           at SimpleInjector.Container.ThrowMissingInstanceProducerException(Type serviceType)
           at SimpleInjector.Container.GetInstanceFromProducer(InstanceProducer instanceProducer, Type serviceType)
           at SimpleInjector.Container.GetInstanceForType[TService]()
           at SimpleInjector.Container.GetInstance[TService]()
           at MyWebApp.Web.MvcApplication.Application_PostAuthenticateRequest() in c:\Projects\MyWebApp\Client\\MyWebApp.Web\Global.asax.cs:line 46
      InnerException: