2013-03-11 10 views
8

मैं अपने एएसपी .NET एमवीसी 4 प्रोजेक्ट में आईओसी के लिए ऑटोफैक का उपयोग कर रहा हूं। ऑटोफैक को भंडार शुरू करने में कुछ परेशानी हो रही है और इसे एपीआई नियंत्रक पर पास कर रहा है।ऑटोफैक और एएसपी .NET एमवीसी 4 वेब एपीआई

मुझे यकीन है कि मुझे मेरी कॉन्फ़िगरेशन में कुछ याद आ रहा है।

आईओसी Bootstrapper:

public static class Bootstrapper 
{ 
    public static void Initialize() 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
     builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 

     builder.Register(x => new SharePointContext(HttpContext.Current.Request)).As<ISharePointContext>().SingleInstance(); 
     builder.RegisterType<SharePointRepository<IEntity>>().As<IRepository<IEntity>>(); 
     builder.RegisterType<SharePointContextFilter>().SingleInstance(); 

     builder.RegisterFilterProvider(); 

     IContainer container = builder.Build(); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

     var resolver = new AutofacWebApiDependencyResolver(container); 
     GlobalConfiguration.Configuration.DependencyResolver = resolver; 
    } 
} 

IRepository https://localhost:44305/api/integration

<Error> 
    <Message>An error has occurred.</Message> 
    <ExceptionMessage> 
     None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 
     on type 'EL.Web.Controllers.API.IntegrationController' can be invoked with 
     the available services and parameters: Cannot resolve parameter 
     'EL.Web.Infrastructure.IRepository`1[EL.Web.Models.Integration] repository' of 
     constructor 'Void .ctor(EL.Web.Infrastructure.IRepository`1[EL.Web.Models.Integration])'. 
    </ExceptionMessage> 
    <ExceptionType>Autofac.Core.DependencyResolutionException</ExceptionType> 
    <StackTrace> 
     at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) 
     at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) 
     at Autofac.Core.Resolving.InstanceLookup.Execute() 
     at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) 
     at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) 
     at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) 
     at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) 
     at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) 
     at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters) 
     at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters) 
     at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType) 
     at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType) 
     at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) 
     at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) 
    </StackTrace> 
</Error> 

यहाँ कोड के कुछ प्रासंगिक बिट कर रहे हैं: जब मैं करने के लिए नेविगेट

यहाँ त्रुटि मैं मिलता है:

public interface IRepository<T> 
{ 
    void Add(T entity); 

    void Delete(int id); 

    IEnumerable<T> Find(Expression<Func<T, bool>> filter = null); 

    void Update(int id, T entity); 
} 

SharePointRepository:

internal class SharePointRepository<T> : IRepository<T> where T : IEntity 
{ 
    private readonly ISharePointContext _context; 
    private readonly string _listName; 

    internal SharePointRepository(ISharePointContext context) 
    { 
     _context = context; 

     object[] attributes = typeof (T).GetCustomAttributes(typeof (SharePointListAttribute), false); 

     if (!attributes.Any()) 
     { 
      throw new Exception("No associated SharePoint list defined for " + typeof (T)); 
     } 

     _listName = ((SharePointListAttribute) attributes[0]).ListName; 
    } 

    public void Add(T entity) 
    { 
     throw new NotImplementedException(); 
    } 

    public void Delete(int id) 
    { 
     throw new NotImplementedException(); 
    } 

    public IEnumerable<T> Find(Expression<Func<T, bool>> filter) 
    { 
     throw new NotImplementedException(); 
    } 

    public void Update(int id, T entity) 
    { 
     throw new NotImplementedException(); 
    } 
} 

IntegrationController:

public class IntegrationController : ApiController 
{ 
    private readonly IRepository<Integration> _repository; 

    public IntegrationController(IRepository<Integration> repository) 
    { 
     _repository = repository; 
    } 

    public void Delete(Guid integrationId) 
    { 
     _repository.Delete(Get(integrationId).Id); 
    } 

    public IEnumerable<Integration> Get() 
    { 
     return _repository.Find(); 
    } 

    public Integration Get(Guid integrationId) 
    { 
     return _repository.Find(i => i.IntegrationId == integrationId).FirstOrDefault(); 
    } 

    public void Post([FromBody] Integration integration) 
    { 
     _repository.Add(integration); 
    } 

    public void Put(Guid integrationId, [FromBody] Integration integration) 
    { 
     _repository.Update(Get(integrationId).Id, integration); 
    } 
} 

IEntity:

internal interface IEntity 
{ 
    int Id { get; } 
} 

निकाय:

public abstract class Entity : IEntity 
{ 
    protected Entity(int id) 
    { 
     Id = id; 
    } 

    public int Id { get; private set; } 
} 

एकता:

[SharePointList("Integrations")] 
public class Integration : Entity 
{ 
    public Integration(int id) : base(id) 
    { 
    } 

    public string ApiUrl { get; set; } 

    public bool DeletionAllowed { get; set; } 

    public Guid IntegrationId { get; set; } 

    public string Key { get; set; } 

    public string List { get; set; } 

    public bool OutgoingAllowed { get; set; } 

    public string RemoteWeb { get; set; } 

    public string Web { get; set; } 
} 
+0

परिभाषित " "। क्या आपने इसे पढ़ा? http://www.asp.net/web-api/overview/extensibility/using-the-web-api- निर्भरता-resolver –

उत्तर

9

आप अपने IRepository गलत पंजीकृत किया है। रेखा के साथ:

builder.RegisterType<SharePointRepository<IEntity>>().As<IRepository<IEntity>>(); 

आप Autofac को बताया कि जब भी किसी का अनुरोध करेंगे एक IRepository<IEntity> उन्हें एक SharePointRepository<IEntity> देते हैं, लेकिन आप एक ठोस IRepository<Integration> ताकि आप एक अपवाद मिल अनुरोध कर रहे हैं।

आपको क्या चाहिए open generic registration feature of Autofac। तो अपने पंजीकरण बदलने के लिए:

builder.RegisterGeneric(typeof(SharePointRepository<>)) 
     .As(typeof(IRepository<>)); 

के रूप में आप आप उम्मीद करेंगे जब आप एक IRepository<Integration> यह एक SharePointRepository<Integration> दे देंगे के लिए पूछना यह काम करेंगे।

आपके पास दूसरी असंबद्ध समस्या भी है: आपके SharePointRepository में केवल internal कन्स्ट्रक्टर है।

Autofac डिफ़ॉल्ट रूप से केवल public निर्माताओं के लिए लग रहा है तो आप या तो public करने के लिए अपने निर्माता और वर्ग बदलने के लिए या आप FindConstructorsWith विधि के साथ Nonpublic निर्माताओं के लिए देखने के लिए Autofac को बताने की आवश्यकता: कुछ परेशानी हो रही

builder 
    .RegisterType<SharePointRepository<IEntity>>() 
    .FindConstructorsWith(
     new DefaultConstructorFinder(type => 
      type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance))) 
    .As<IRepository<IEntity>>(); 
+0

इससे मुझे उस समस्या को हल करने में मदद मिली जो मैंने शुरू में किया था। लेकिन, अब मुझे एक नई त्रुटि मिलती है: 'टाइप पर कोई कन्स्ट्रक्टर' EL.Web.Infrastructure.SharePointRepository'1 [EL.Web.Models.Integration] 'कन्स्ट्रक्टर खोजक' Autofac.Core.Activators.Reflection के साथ पाया जा सकता है। DefaultConstructorFinder''। मैं यहां थोड़ा उलझन में हूं। मैंने पहले से ही 'SharePointContext' को' ISharePointContext' के रूप में उपयोग करने के लिए परिभाषित किया है - और यह भंडार की आवश्यकता का एकमात्र पैरामीटर है। – Moon

+0

आपकी समस्या यह है कि आपकी 'SharePointRepository1' कक्षा में केवल आंतरिक कन्स्ट्रक्टर हैं। मेरा अद्यतन उत्तर देखें। – nemesv

संबंधित मुद्दे