WebApi

11

में एकता के साथ प्रति अनुरोध dbcontext को हल करना मैं इस काम को करने के लिए संघर्ष कर रहा हूं। मैं एकता और Unity.AspNet.WebApi संकुल (v 1404/05/03) मिल गया है स्थापित किया है और सक्रियण कोड जो संकुलWebApi

public static class UnityWebApiActivator 
{ 
    /// <summary>Integrates Unity when the application starts.</summary> 
    public static void Start() 
    { 
     var container = UnityConfig.GetConfiguredContainer(); 
     var resolver = new UnityHierarchicalDependencyResolver(container); 

     GlobalConfiguration.Configuration.DependencyResolver = resolver; 

     // 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 static void RegisterTypes(IUnityContainer container) 
     { 
      container.RegisterType<IAuditService, AuditService>(
       new PerThreadLifetimeManager(), 
       new InjectionConstructor(new SecurityDbContext())); 
     } 

अब तक मैंने बिना सफलता के PerThreadLifetimeManager और TransientLifetimeManager को आजमाया है। मुझे यूनिटी.एमवीसी पैकेज भी मिला है और msdn द्वारा सुझाए गए अनुसार PerRequestLifetimeManager का उपयोग करने की कोशिश की लेकिन कोई भाग्य नहीं है। यह हमेशा मुझे dbcontex का एक ही उदाहरण देता है।

मैं किसी भी एमवीसी निर्भरता को शामिल नहीं करता क्योंकि यह पूरी तरह से वेबएपी है लेकिन जब मैं यूनिटी.एमवीसी का उपयोग करने की कोशिश करता हूं, तो मैंने कुछ http रनटाइम त्रुटियों को भी समाप्त कर दिया।

किसी के पास वेबएपी में एकता के साथ प्रति अनुरोध dbcontext को हल करने के लिए कोई अच्छा सुझाव/उदाहरण है, अधिमानतः बिना किसी एमवीसी निर्भरता के?

उत्तर

12

जिस तरह से मैं डीबी संदर्भ इंजेक्शन दे रहा था वह समस्या थी। एकता ने बनाए गए उदाहरण को याद किया और बनाया गया सभी नए ऑडिट सेवा उदाहरण के लिए एक ही उदाहरण इंजेक्ट किया। मुझे बस नीचे डीबी संदर्भ को हल करने की आवश्यकता है।

container.RegisterType<DbContext, SecurityDbContext>(new PerThreadLifetimeManager()); 

PerThreadLifetimeManager काम किया है और यह प्रत्येक वेब अनुरोध एक अलग धागा द्वारा परोसा जाएगा पर विचार ठीक होना चाहिए।

+0

इस 'SecurityDbContext' प्राप्त करने में सक्षम। क्या यह स्वयं एक वर्ग को परिभाषित करता है जो डीबोनटेक्स्ट क्लास को विरासत में ले रहा है? – picnic4u

+0

हां सुरक्षा डीबीकॉन्टेक्स्ट डीबीकॉन्टेक्स्ट को विरासत में लेता है और यह वह जगह है जहां मैं ऑनमोडेल क्रिएटिंग विधि को ओवरराइड करके ईएफ मैपिंग जोड़ता हूं। – Otake

+0

@ ओटेक इसे नियंत्रक पर कैसे घोषित किया जाता है ताकि यह काम करे? TKS – Pascal

1

मैं वेब एपीआई कॉन्फिग क्लास के भीतर अपनी कस्टम यूनिटी रीसोल्वर की कक्षा घोषित करके प्रति अनुरोध को हल करने में कामयाब रहा। UnityResolver क्लास Http कॉन्फ़िगरेशन क्लास का उपयोग करता है मानते हुए कि आप ओविन संदर्भ का उपयोग कर रहे हैं।

private static void RegisterReleaseEnv(IUnityContainer container) 
     { 
      //Repository Registration 
      container    
       .RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager()); 

     } 

यह बहुत महत्वपूर्ण है, ताकि आप प्रति एक नया उदाहरण मिल है कि आप HierarchicalLifetimeManager जीवन प्रबंधक का उपयोग है:

public static void Register(HttpConfiguration config) 
     {  
      // Web API configuration and services 
      var _container = new UnityContainer(); 
      DependencyConfiguration.ConfigureContainer(_container); 
      config.DependencyResolver = new UnityResolver(_container); 
     } 

ConfigureContainer वर्ग बस एक वर्ग जहां मैं अपने आईओसी निर्भरता की घोषणा के रूप में नीचे दिखाया गया है निवेदन।

UnityResolver वर्ग तो इस तरह दिखता है:

public class UnityResolver : IDependencyResolver 
    { 
     protected IUnityContainer container; 

     public UnityResolver(IUnityContainer container) 
     { 
      if (container == null) 
      { 
       throw new ArgumentNullException("container"); 
      } 
      this.container = container; 
     } 

     public object GetService(Type serviceType) 
     { 
      try 
      { 
       return container.Resolve(serviceType); 
      } 
      catch (ResolutionFailedException) 
      { 
       return null; 
      } 
     } 

     public IEnumerable<object> GetServices(Type serviceType) 
     { 
      try 
      { 
       return container.ResolveAll(serviceType); 
      } 
      catch (ResolutionFailedException) 
      { 
       return new List<object>(); 
      } 
     } 

     public IDependencyScope BeginScope() 
     { 
      var child = container.CreateChildContainer(); 
      return new UnityResolver(child); 
     } 

     public void Dispose() 
     { 
      container.Dispose(); 
     } 
    } 

मैं तो एक सामान्य Repistory उपयोग कर एक नया डीबी संदर्भ के रूप में नीचे दिखाया गया है:

public class GenericRepository<TEntity> : IRepository<TEntity>, IDisposable where TEntity : class 
{ 
    internal BackendContainer context; 
    internal DbSet<TEntity> dbSet; 

    public GenericRepository(BackendContainer context) 
    { 
     this.context = context; 
     this.dbSet = context.Set<TEntity>(); 
    } 

    public GenericRepository() 
     : this(new BackendContainer()) 
    { 
    } 


    public virtual IQueryable<TEntity> All() 
    { 
     return dbSet.AsQueryable(); 
    } 
} 
एकता रिज़ॉल्वर, सामान्य भंडार की वजह से

प्रति अनुरोध तत्काल है और इसलिए डीबीकॉन्टेक्स्ट (बैकएंडकंटनर) है।

मुझे उम्मीद है कि इससे मदद मिलती है।

अधिक जानकारी के लिए: http://www.asp.net/web-api/overview/advanced/dependency-injection

नहीं