2017-05-10 49 views
3

我想在我的MVC應用程序中設置一個自定義的身份驗證過濾器,但我需要在身份驗證過濾器中引用我的用戶服務。設置我的服務,團結,像這樣:從Unity獲取接口的實例

private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => 
    { 
     var container = new UnityContainer(); 
     RegisterTypes(container); 
     return container; 
    }); 

    public static IUnityContainer GetConfiguredContainer() 
    { 
     return container.Value; 
    } 

    public static void RegisterTypes(IUnityContainer container) 
    { 

     // container.LoadConfiguration(); 

     // TODO: Register your types here 
     container.RegisterType<IUserService, UserService>(); 

    } 

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(GERPWeb.App_Start.UnityWebActivator), "Start")] 
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(GERPWeb.App_Start.UnityWebActivator), "Shutdown")] 

namespace APP.App_Start 
{ 
/// <summary>Provides the bootstrapping for integrating Unity with ASP.NET MVC.</summary> 
public static class UnityWebActivator 
{ 
    /// <summary>Integrates Unity when the application starts.</summary> 
    public static void Start() 
    { 
     var container = UnityConfig.GetConfiguredContainer(); 

     FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First()); 
     FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container)); 

     DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 

     // TODO: Uncomment if you want to use PerRequestLifetimeManager 
     // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule)); 
    } 

    /// <summary>Disposes the Unity container when the application is shut down.</summary> 
    public static void Shutdown() 
    { 
     var container = UnityConfig.GetConfiguredContainer(); 
     container.Dispose(); 
    } 
} 

能正常工作的每個地方我可以有一個構造函數,像這樣:

public class UserController : BaseController 
{ 

    private readonly IUserService _userService; 

    public CustomerController(IUserService userService) 
    { 
     _userService = userService; 

    } 

但我不能有一個對我的身份驗證過濾器:

public class BasicAuthorization : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     //see if we can skip the authorization 
     bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || 
           filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(
            typeof(AllowAnonymousAttribute), true); 

     if (!skipAuthorization) 
     { 
      //var userService = ServiceLocator.Current.GetInstance<IUserService>(); 
      //get instance of user service here 


      base.OnAuthorization(filterContext); 
     } 
    } 
} 

然後在我的FilterConfig.cs:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new BasicAuthorization()); 
     filters.Add(new HandleErrorAttribute()); 
    } 

我發現了一個對服務定位器的引用,並試圖盡我所能地使用它,但我想我錯過了一些東西,因爲我在該行上獲得了ServiceLocationProvider must be set.,並且所有的谷歌鏈接都是針對WPF的。

我在這裏錯過了什麼?

回答

2

您已經設置了DependencyResolver,它基本上遵循服務定位器模式。

public class BasicAuthorization : AuthorizeAttribute { 
    public override void OnAuthorization(AuthorizationContext filterContext) { 
     //see if we can skip the authorization 
     bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || 
           filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(
            typeof(AllowAnonymousAttribute), true); 

     if (!skipAuthorization) { 
      //Using dependency resolver here 
      var userService = (IUserService) DependencyResolver.Current.GetService(typeof(IUserService)); 


      base.OnAuthorization(filterContext); 
     } 
    } 
} 

您可以創建一個擴展方法以允許例如

public static T GetService<T>(this IDependencyResolver container) { 
    return (T)container.GetService(typeof(T)); 
} 

更清潔的決議,將允許

var userService = DependencyResolver.Current.GetService<IUserService>();