asp.net-mvc-4 – Autofac和ASP .Net MVC 4 Web API

前端之家收集整理的这篇文章主要介绍了asp.net-mvc-4 – Autofac和ASP .Net MVC 4 Web API前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在ASP .Net MVC 4项目中使用Autofac for IoC. Autofac在初始化存储库并将其传递给API控制器时遇到一些问题.

我确信我的配置中缺少一些东西.

这是我在导航到以下时遇到的错误: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,IEnumerable`1 parameters) 
        at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context,Type serviceType,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>

以下是一些相关的代码

IoC 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:

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

解决方法

您已将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只有一个内部构造函数.

默认情况下,Autofac只查找公共构造函数,因此您可以将构造函数和类更改为public,或者需要告诉Autofac使用FindConstructorsWith方法查找NonPublic构造函数

builder
    .RegisterType<SharePointRepository<IEntity>>()
    .FindConstructorsWith(
       new DefaultConstructorFinder(type => 
          type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance))) 
    .As<IRepository<IEntity>>();
原文链接:https://www.f2er.com/aspnet/248478.html

猜你在找的asp.Net相关文章