2016-09-01 1 views
0

Ich habe ein Problem mit benutzerdefinierten Aktionsfiltern und Abhängigkeitsinjektionen. Hier ist mein Code:Abhängigkeitsinjektion für benutzerdefinierten ActionFilter mit Unity.MVC

PageCount.cs

public class PageCount : ActionFilterAttribute 
{ 
    [Dependency] 
    public IVisitorService _visitorService { get; set; } 

    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     _visitorService.AddVisitorCount(); 
     base.OnResultExecuted(filterContext); 
    } 
} 

IVisitorService.cs

public partial interface IVisitorService 
{ 
    int GetVisitorsCount(); 
    void AddVisitorCount(); 
} 

VisitorService.cs

public partial class VisitorService : IVisitorService 
{ 
    private readonly IRepository<Visitor> _visitorRepository; 

    public VisitorService(IRepository<Visitor> visitorRepository) 
    { 
     _visitorRepository = visitorRepository; 
    } 

    public int GetVisitorsCount() 
    { 
     Visitor v = _visitorRepository.Get(1); 

     return v.VisitCount; 
    } 

    public void AddVisitorCount() 
    { 
     Visitor v = _visitorRepository.Get(1); 
     v.VisitCount += 1; 
     _visitorRepository.Update(v); 
    } 
} 

UnityConfig.cs

public static void RegisterComponents() 
{ 
    var container = new UnityContainer(); 

    // identity 
    container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager()); 
    container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager()); 
    container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(new ApplicationDbContext())); 
    container.RegisterType<AccountController>(new InjectionConstructor()); 
     container.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication)); 

    container.RegisterType(typeof(IRepository<>), typeof(Repository<>)); 
    container.RegisterType<IGameService, GameService>(); 
    container.RegisterType<IGenreService, GenreService>(); 
    container.RegisterType<IVisitorService, VisitorService>(); 

    DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 
} 

UnityMvcActivator.cs

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


Fehler

Der aktuelle Typ GameCommerce.Infrastructure.Services.Visitors.IVisitorService ist eine -Schnittstelle und kann nicht erstellt werden. Vermissen Sie ein Typ-Mapping?

Antwort

3

Das Problem ist, dass MVC nicht den Container verwendet, den Sie in Ihrer RegisterTypes-Methode in UnityConfig.cs eingerichtet haben. Am Ende des RegisterTypes in UnityConfig.cs, setzen Sie DependencyResolver.Current auf einen Container, die Sie innerhalb der Methode erstellt haben, aber später in UnityMvcActivator.cs wird DependencyResolver.Current mit UnityConfig.GetConfiguredContainer() überschrieben, die nicht Ihre Eintragungen enthält.

Ich empfehle Ihnen, die UnityConfig.cs Klasse mit dem Unity.Mvc Paket bereitgestellt verwenden, ohne Ihre Änderungen an der RegisterTypes Methode wie folgt:

UnityConfig. cs

public class UnityConfig 
{ 
    #region Unity Container 
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => 
    { 
     var container = new UnityContainer(); 
     RegisterTypes(container); 
     return container; 
    }); 

    /// <summary> 
    /// Gets the configured Unity container. 
    /// </summary> 
    public static IUnityContainer GetConfiguredContainer() 
    { 
     return container.Value; 
    } 
    #endregion 

    /// <summary>Registers the type mappings with the Unity container.</summary> 
    /// <param name="container">The unity container to configure.</param> 
    /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
    /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks> 
    public static void RegisterTypes(IUnityContainer container) 
    { 
     // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements. 
     // container.LoadConfiguration(); 

     // TODO: Register your types here 
     container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager()); 
     container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager()); 
     container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(new ApplicationDbContext())); 
     container.RegisterType<AccountController>(new InjectionConstructor()); 
     container.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication)); 

     container.RegisterType(typeof(IRepository<>), typeof(Repository<>)); 
     container.RegisterType<IGameService, GameService>(); 
     container.RegisterType<IGenreService, GenreService>(); 
     container.RegisterType<IVisitorService, VisitorService>(); 
    } 

Auf diese Weise DependencyResolver.Current wird nur einmal fertig, in UnityMvcActivator.cs.

+0

danke. für die Antwort, aber es wirft Nullbezug. ** "Objektreferenz wurde nicht auf eine Instanz eines Objekts gesetzt." ** von diesem Methodenaufruf ** _ visitorService.AddVisitorCount(); ** on PageCount.cs – markoverflow

+0

Eine Nullreferenzausnahme bedeutet, dass Ihre Abhängigkeiten jetzt ordnungsgemäß aufgelöst werden. Können Sie debuggen und sehen, was null ist? Ist '_visitorService' null? Ist das _visitorRepository innerhalb der Methode 'AddVisitorCount()' null? Oder gibt '_visitorRepository' in der' AddVisitorCount() 'Methode einen Null' Visitor' zurück? –

+0

@Correy Smith Hallo, ich füge den Haltepunkt in der ** VisitorService.cs **, die Konstruktoren und andere Sachen funktioniert gut, bis der Schritt zu erreichen ** öffentliche IVisitorService _visitorService {bekommen; einstellen; } **. Das Feld ** _ visitorService ** ist null. – markoverflow

1

Haben Sie darüber nachgedacht, Ihr Attribut in ein "passives" Attribut aufzuteilen, wie in diesem Artikel beschrieben?

http://blog.ploeh.dk/2014/06/13/passive-attributes/

Von Ihrer Implementierung verwenden Sie Eigenschaft Injektion da nicht zur Verfügung Injektion Konstruktor ist, weil Sie nur Konstanten und Literale zu einem Attribut passieren kann. Aber Sie sollten wirklich die Konstruktorinjektion verwenden, da Ihre Abhängigkeit erforderlich ist und ohne den Verweis auf IVisitorService nicht funktioniert. (Eigenschaftsinjektion bezeichnet üblicherweise eine optionale Abhängigkeit.)

Wenn Sie dem Beispiel in diesem Artikel folgen, erstellen Sie eine nette Trennung von Problemen und erleichtern das Problem, das Sie mit dem IoC-Framework haben.

Verwandte Themen