Autofac et ASP .Net MVC 4 Web API
Je suis en utilisant Autofac pour les Cio dans mes ASP .Net MVC 4 du projet. Autofac est un problème de l'initialisation du référentiel et en passant à la API Contrôleur.
Je suis sûr que je suis absent quelque chose dans ma configuration.
Voici l'erreur que j'obtiens lorsque je navigue à: 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>
Ici sont quelques uns des morceaux de code:
Cio Programme D'Amorçage:
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:
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; }
}
Entité:
public abstract class Entity : IEntity
{
protected Entity(int id)
{
Id = id;
}
public int Id { get; private set; }
}
Intégration:
[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; }
}
définir "un problème". Avez-vous lu cela? asp.net/web-api/overview/extensibility/...
OriginalL'auteur Moon | 2013-03-11
Vous devez vous connecter pour publier un commentaire.
Vous avez enregistré votre
IRepository
mal. Avec la ligne:Vous dit Autofac qu'à chaque fois que quelqu'un demande un
IRepository<IEntity>
leur donner unSharePointRepository<IEntity>
, mais vous demandez un bétonIRepository<Integration>
de sorte que vous obtenez une exception.Ce que vous avez besoin est la ouvrir générique de la fonction d'enregistrement de Autofac. Afin de modifier votre inscription à:
Il fonctionnera comme vous pouvez vous attendre lorsque vous demandez pour un
IRepository<Integration>
il donnera unSharePointRepository<Integration>
.Vous avez également un deuxième problème sans rapport avec: votre
SharePointRepository
n'a qu'uneinternal
constructeur.Autofac par défaut ne regarde que pour
public
constructeurs afin de vous changer votre constructeur de classe et depublic
ou vous avez besoin de dire à Autofac chercher Confidentielles les constructeurs avec leFindConstructorsWith
méthode:No constructors on type 'EL.Web.Infrastructure.SharePointRepository
1[EL.Web.Modèles.L'intégration] " peut être trouvé avec le constructeur finder 'Autofac.De base.Activateurs.De la réflexion.DefaultConstructorFinder'. I am a little confused here. I have already defined to use
SharePointContext " commeISharePointContext
-- et c'est le seul paramètre du référentiel besoins.Le problème est que votre
SharePointRepository1
classe a seulement internes des constructeurs. Voir ma réponse mis à jour.OriginalL'auteur nemesv