使用通用库结合autofac用的WebAPI [英] Binding autofac with webapi using generic repository

查看:232
本文介绍了使用通用库结合autofac用的WebAPI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用一个仓库使用autofac,我试图加一点泛型尝试减少重复code的我writing.However我转圈圈试图让autofac为工作量我

I am trying to use autofac with a repository and I am trying to add a little generics to try reducing the amount of duplicate code I am writing.However I am going round in circles trying to get autofac to work for me

所以,我创建了一个的DomainService和接口处理我们的标准CRUD操作

So I created a domainservice and interface that handles our the standard crud operations

public class DomainService<T>:IDomainService<T>
{
    protected readonly IDomainService<T> Repository;

    public DomainService(IDomainService<T> repository)
    {
        Repository = repository;
    }



    public IQueryable<T> GetQueryable()
    {
        return Repository.GetQueryable();
    }

    public virtual Task<T> Add(T entity)
    {
       return Repository.Add(entity);
    }

接口:

public interface IDomainService<T>
{
    IQueryable<T> GetQueryable();
    Task<T> Add(T entity);
    Task<bool> Delete(T entity);
    Task<T> Update(T entity);
    Task<T> GetById(int id);
    Task<T> GetByUID(Guid id);
}

我用我的回购是没有什么特别的。

I am using my repo is nothing special

public class SkillRepository : DomainService<Skill>, ISkill
{
    private DataContext _db = new DataContext();
    private readonly ILogger _log = null;

    public SkillRepository(IDomainService<Skill> repository, ILogger log) : base(repository)
    {
        _log = log;
    }
}

最后,我线了autofac:

Finally where I wire up autofac:

 var builder = new ContainerBuilder();

// Register the Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

// Register other dependencies.
builder.Register(c => new Logger()).As<ILogger>().InstancePerApiRequest();

builder.RegisterType<SkillRepository>()
    .As<IDomainService<Skill>>()
    .As<ISkill>()
    .InstancePerRequest();

// Build the container.
var container = builder.Build();

// Create the depenedency resolver.
var resolver = new AutofacWebApiDependencyResolver(container);

// Configure Web API with the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver = resolver;

我的Web API控制器看起来像

My web api controller looks like

public class SkillsController : BaseController<Skill>
{
    private readonly ISkill _skillRepository;

    public SkillsController(SkillRepository skillRepository) : base(skillRepository)
    {
        _skillRepository = skillRepository;
    }
}

BaseController

BaseController

public abstract class BaseController<TEntity> : ApiController
    where TEntity : new()
{
    protected readonly IDomainService<TEntity> DomainService;

    protected BaseController(IDomainService<TEntity> domainService)
    {
        DomainService = domainService;
    }

我得到一个异常:

I get an exception:

的建设者没有发现
  在类型'Autofac.Core.Activators.Reflection.DefaultConstructorFinder
  'Api.EndPoints.Skills.SkillsController'可以与被调用
  提供的服务及参数:\\ \\无法解析参数
  Domain.Repository.SkillRepository skillRepository构造
  虚空.ctor(Domain.Repository.SkillRepository)'。

"None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Api.EndPoints.Skills.SkillsController' can be invoked with the available services and parameters:\ \ Cannot resolve parameter 'Domain.Repository.SkillRepository skillRepository' of constructor 'Void .ctor(Domain.Repository.SkillRepository)'."

有什么明显的,我做错了什么?

Is there something obvious that I am doing wrong?

推荐答案

它无法解析的依赖,因为它寻找的具体类型,但你永远不注册 SkillsRepository 作为。现在,你可以改变登记注册的具体类型,但是这不会是最好的办法。

It cannot resolve the dependency because it's looking for the concrete type but you never registered SkillsRepository as that. Now you could change the registration to register the concrete type but that wouldn't be the best approach.

有一个更好的方法是注册SkillsRepository作为它的接口:

A better approach is to register SkillsRepository as its interfaces:

builder.RegisterType<SkillRepository>()
    .As<ISkillsRepository>()
    .InstancePerRequest();

和定义 ISkillsRepository 继承所需的所有其它接口,如 ISkill

And define ISkillsRepository to inherit all the other interfaces like ISkill that you want.

public interface ISkillsRepository : ISkill, IDomainService<Skill> { }

不注册对象作为具体类型,不要在构造函数依赖于具体类型。

  public SkillsController(ISkillRepository skillRepository) : 
      base(skillRepository) ...

如果您使用的具体类型,依赖你创建一个不能用嘲讽的框架测试类。

If you use concrete types as dependencies you create classes that cannot be tested using mocking frameworks.

您使用 SkillRepository的:&DomainService的LT;技巧&gt;中ISkill 的困扰了。为什么既是技能和技能域名服务?没有太大的意义。

Your use of SkillRepository : DomainService<Skill>, ISkill is perplexing too. Why is it both a skill and a domain service for skills? Doesn't make much sense.

这篇关于使用通用库结合autofac用的WebAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆