0

我有以下類/ intefaces一個服務層(IServices是一個空的接口):的IoC - Autofac並註冊與相同的通用接口的多個服務

public interface IForoChanService<T> : IService 
{ 
    T GetById(int id); 

    IQueryable SearchBy(Expression<Func<T, bool>> predicate); 

    IEnumerable<T> GetAll(); 

    int Create(T entity); 

    void CreateMany(IEnumerable<T> entities); 

    void Delete(T entity); 

    void Delete(int id); 

    void DeleteMany(IEnumerable<T> entities); 

    void Update(T entity); 

} 

然後,我有一個抽象類執行這一簽名一般:

public abstract class ForoChanServiceBase<T> : IForoChanService<T> where T : EntityBase 
{ 
    public T GetById(int id) 
    { 
     return ChanDbContext.Set<T>().Find(id); 
    } 
    //all the other methods as well 
} 

最後的具體類:

public class CategoryService : ForoChanServiceBase<Category> 
{ 

} 

我想使用AutoFac注入這些服務:在構造函數(多類別,客戶等):我有一個基本的控制器:

public abstract class ForoChanBaseController: Controller 
{ 

    protected ForoChanServiceBase<Post> PostService { get; private set; } 
    protected ForoChanServiceBase<Comment> CommentService { get; private set; } 
    protected ForoChanServiceBase<Category> CategoryService { get; private set; } 

    protected ForoChanBaseController() 
    { 

    } 

    protected ForoChanBaseController(
     ForoChanServiceBase<Post> postService, 
     ForoChanServiceBase<Comment> commentService, 
     ForoChanServiceBase<Category> categoryService) 
    { 
     PostService = postService; 
     CommentService = commentService; 
     CategoryService = categoryService; 
    } 

} 

而且我設置autofac這樣的:

 public static void ConfigureIoc() 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterType<CommentService>().As<ForoChanServiceBase<Comment>>().InstancePerRequest(); 
     builder.RegisterType<CategoryService>().As<ForoChanServiceBase<Category>>().InstancePerRequest(); 
     builder.RegisterType<PostService>().As<ForoChanServiceBase<Post>>().InstancePerRequest(); 

     builder.Build(); 
    } 

的問題是,我有被當控制器我需要使用任何服務方法,那傢伙(CategoryService)爲空:

 public ActionResult Create() 
    { 
     var p = new PostFormNewVm 
     { 
      Categories = CategoryService.GetAll().Select(c => new CategoryVm { Id = c.Id, Title = c.Title }) 
     }; 

     return View(p); 
    } 

旁邊這個錯誤是否我做錯了什麼?我無法讓它工作。

我也嘗試過inteface。

+1

你的問題在默認構造函數中,protected ForoChanBaseController(){}。刪除它,它應該工作。您可能需要在實施此「ForoChanBaseController」控制器的地方修復您的課程。 – Prashant

回答

2

您的ForoChanBaseController包含多個構造函數,其中is an anti-pattern。由於此默認構造函數的存在,所以有一個派生類使用此構造函數而不是重載的類,這會導致依賴項爲null

雖然這個默認的構造函數是事業,爲你在這裏發表的問題,也有你的設計更加稀少明顯problems-:

  • 雖然可以刪除默認的構造函數,防止有這個基類在所有。基礎類通常是單一責任原則的違規行爲,要麼被用於填充橫切關注點或其他效用函數。通過讓這個基類派生類型被迫需要它們甚至可能根本不用的依賴關係。這會使代碼複雜化並使測試複雜化。
  • 既然你有接口IForoChanService<T>,消費者不應該依賴於基類ForoChanServiceBase。事實上,和以前一樣的建議認爲:這個基類應該根本不存在。
  • IForoChanService<T>是方法的大型通用工具箱,其中消費者一次只使用一種或兩種方法。這意味着您違反了Interface Segregation Principle
  • IForoChanService<T>實施可能會違反Liskov Substitution Principle,因爲會有不允許實體被刪除的實現。這將導致致電Delete失敗,但不存在該實體的例外情況,而不是Delete
+0

非常感謝您的親切看法。我的問題是,我是否應該刪除實現通用metods的基類並直接實現每個類中的接口?我不是在那裏重複自己嗎?那裏推薦的最佳實踐是什麼? – MRFerocius

相關問題