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

相关问题