2011-07-29 41 views
0

我避免在我的Isession注入到每一个控制器,这样就避免了这一点:Ninject with a base controller?管理的ISession在基本控制器...

我试图访问我的基地控制器内我的IRepository,所以我可以在我的应用程序中使用它,使用下面的第二种方法管理对象的生命期是否存在问题?基本上我只希望每次我需要它每次动作请求时重新创建......

//使用Ninject注入......

private readonly IReadOnlySession _repo; 
    public SimpleController(IReadOnlySession repo) 
    { 
     _repo = repo; 
    } 

//从基本控制器获取 - >我的首选方法...

public abstract class AbstractBaseController : Controller 
{ 
    public AbstractBaseController() { } 

private static IReadOnlyGenericRepository readonlysession; 
public static IReadOnlyGenericRepository ReadOnlySession 
{ 
    get { return (readonlysession ?? (readonlysession = new ReadOnlyGenericRepository())); } 
} 
} 

//然后访问使用

var detail = ReadOnlySession.Single<Cat>(x=> x.CatID== _catid); 

IReadOnlyGenericRepository简单地来回继承m:

public interface IReadOnlySession 
    { 
     T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class, new(); 
     System.Linq.IQueryable<T> All<T>() where T : class, new(); 
    } 

更新:在我的AbstractBaseController中声明下面的代码,可以实现单元测试吗?

private IReadOnlySession readonlysession; 
public IReadOnlySession _repo 
{ 
    get { return (readonlysession ?? (readonlysession = GetReadOnlySession())); } 
} 

protected virtual IReadOnlySession GetReadOnlySession() 
{ 
    return new ReadOnlyGenericRepository(); 
} 

回答

2

您还引入了一个固定的依赖关系ReadOnlyGenericRepository。而且我认为单位测试和实施都将不太理解/可读。就我个人而言,我认为这个解决方案给了你更多和更差的负面点,而不是因为你不需要添加一个构造器参数(这是通过Resharper中的简单Alt-Enter来完成的)而获得的。

正:

  • 无需构造函数的参数(或者说不同的看法:保存在ReSharper的单Alt-Enter组合罢工)

负:

  • 修复依赖关系ReadOnlyGenericRepository
  • 需要测试类覆盖GetReadOnlySession()每个控制器
  • 更难理解单元测试和实施

想想也聚集,而不是继承的情况下,有更多的,你必须传递给基构造。

+0

它比这更复杂。无论如何,是的,存在一个固定的依赖关系 - 但正如你所说的,你可以覆盖,因为我有一个抽象的基础控制器 - 它可以很容易地在一个地方和其他地方重写。我们可以说它还不太容易理解吗?那不是开发人员偏好使用Composition而不是继承? – Haroon

+0

当我需要多个接口时,问题就出现了,我总是注入,传递到我的基本控制器上,难道我们不能说在这些情况下会出现好处吗?我的意思是特别是如果行为可以被过度使用... – Haroon

+1

我认为在这情况首先出现问题。如果你需要传递如此多的接口到基地继承可能不是最好的解决方案。正如你所说的那样考虑构图。同时检查是否履行单一责任原则。在大多数情况下,注射很复杂,实施有些问题。 –

1

是否与使用以下方法的第二管理对象的生命周期的任何问题?

单元测试您的控制器在隔离可能有点困难与基本控制器中的这个静态对象。我也不知道这是什么IReadOnlySession应该表示,但是因为它是静态的,它将在所有用户中共享=>所有请求,所以你应该确保它是线程安全的,...我个人更喜欢存储库方法通过DI框架将其注入到控制器中。

+0

有没有办法解决这个问题?我该如何重构?我将如何使它线程安全? – Haroon

+0

@Haroon,通过使用第一种方法并配置您的DI框架为每个控制器实例化一个新的会话=>基本上将它与HTTP请求绑定。以Ninject为例,你可以在配置容器时使用'.InRequestScope()'。 –

+0

如果我想只为我的IRepository避开DI?我仍然会使用Ninject的服务,只要它不是存储库... – Haroon