2014-10-12 12 views
3

我想使用autofac與存儲庫,我試圖添加一點泛型,以減少重複代碼的數量,我正在寫。但是,我正在圍繞圈子試圖獲得autofac工作對我來說使用通用資源庫綁定autapac與webapi

所以我創建了一個的DomainService和界面處理我們的標準CRUD操作

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

我用我的回購是沒有什麼特別的

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:

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控制器看起來像

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

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

BaseController

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

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

我得到了ñ例外:

「與 ‘Autofac.Core.Activators.Reflection.DefaultConstructorFinder’發現式 ‘Api.EndPoints.Skills.SkillsController’建設者都不能與 可用的服務和參數來調用:\\無法解析參數 'Domain.Repository.SkillRepository skillRepository'的構造函數 'Void .ctor(Domain.Repository.SkillRepository)'。「

有什麼明顯的,我做錯了嗎?

回答

3

它無法解析依賴項,因爲它正在尋找具體的類型,但是您從未註冊過SkillsRepository。現在您可以更改註冊以註冊具體類型,但這不是最好的方法。

更好的辦法是註冊SkillsRepository作爲其接口:

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

,並定義ISkillsRepository繼承所有你想要的其它接口,如ISkill

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

請勿將對象註冊爲具體類型,也不要在構造函數中依賴具體類型。

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

如果您使用的具體類型與依賴你創建一個不能用嘲諷框架測試類。

您對SkillRepository : DomainService<Skill>, ISkill的使用也令人費解。爲什麼它既是技能又是技術領域的服務?沒有多大意義。

+0

謝謝伊恩你的詳細解釋。這聽起來像我做的事情有點不對。我已經更新了上面的代碼域名服務,試着展示我正在嘗試做的事情。從本質上講,我試圖使用DomainService作爲從我必須在每個存儲庫上實現IDomainService 的方式。由於每個回購代碼都是相同和無聊的。那有意義嗎? – 2014-10-16 03:58:11

+0

有道理,但是使用Composition而不是Inheritance可能會更好。 http://en.wikipedia.org/wiki/Composition_over_inheritance – 2014-10-16 05:06:47

+0

另外,當您避免使用「Fat Controllers」(通常是正確的做法)時,您很少需要控制器的基類。 – 2014-10-16 05:12:10

1

例外明確規定:

無法解析的構造函數的參數'Domain.Interfaces.ISkill skillRepository '太虛.ctor(Domain.IDomainService`1 [Model.Skill],Domain.Interfaces.ISkill)' 。

您只有IDomainService註冊。但沒有ISkill(該行被評論)。

爲什麼ctor需要2個參數? SkillRepository同時實現了IDomainService<Skill>ISkill,所以你應該能夠把它傳遞:

public SkillsController(SkillRepository skillRepository) : base(skillRepository) 

附:

我的名字是這樣:

public class SkillRepository : ISkillRepository, IDomainService<Skill> 

,我更喜歡一切是要麼多(SkillsControllers,SkillsRepository)或一切奇異(SkillController,SkillRepository)。

+0

嗨@abatishchev我做了上述代碼global.asax的修改。你能發現什麼是錯的嗎?我還沒有辦法解決它 – 2014-10-16 02:37:25

1

在我看來,你應該首先爲你的課程選擇名字,這很難理解代碼本身。其次,您的存儲庫正在實施域服務接口和ISkill,而且這樣的事情正在增加更多的混淆。我很確定,如果你正確地組織你的課程,那麼你會找到解決你的問題。 比如ApiController應該使用域服務,域服務應該使用倉庫,倉庫應該處理物品。

public class SkillsDomainService:ISkillsDomainService 
{ 
    public void AddSkill(string name){} 
    public void DeleteSkillById(int id){} 
    ..... etc 
} 

public class Repository:IRepository 
{ 
    public T Get(int id){} 
    public IEnumerable<T>GetAll(){} 
} 

然後,你需要綁定你的接口到具體歸類於國際奧委會。事情應該這樣工作,我很確定。