Asp.net mvc 3 如何减少控制器上注入依赖项的数量
我首先使用MVC3、实体框架v4.3代码和SimpleInjector。我有几个简单的类,如下所示:Asp.net mvc 3 如何减少控制器上注入依赖项的数量,asp.net-mvc-3,dependency-injection,simple-injector,entity-framework-4.3.1,Asp.net Mvc 3,Dependency Injection,Simple Injector,Entity Framework 4.3.1,我首先使用MVC3、实体框架v4.3代码和SimpleInjector。我有几个简单的类,如下所示: public class SomeThing { public int Id { get; set; } public string Name { get; set; } } public class MainClass { public int Id { get; set; } public string Name { get; set; } publ
public class SomeThing
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MainClass
{
public int Id { get; set; }
public string Name { get; set; }
public virtual AThing AThingy { get; set; }
public virtual BThing BThingy { get; set; }
public virtual CThing CThingy { get; set; }
public virtual DThing DThingy { get; set; }
public virtual EThing EThingy { get; set; }
}
我有另一个实体,看起来像这样:
public class SomeThing
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MainClass
{
public int Id { get; set; }
public string Name { get; set; }
public virtual AThing AThingy { get; set; }
public virtual BThing BThingy { get; set; }
public virtual CThing CThingy { get; set; }
public virtual DThing DThingy { get; set; }
public virtual EThing EThingy { get; set; }
}
每个Thingy(当前)都有自己的Manager类,如下所示:
public class SomeThingManager
{
private readonly IMyRepository<SomeThing> MyRepository;
public SomeThingManager(IMyRepository<SomeThing> myRepository)
{
MyRepository = myRepository;
}
}
实际上,在这个控制器中注入的依赖项是原来的两倍。闻起来很香。当您还知道有一个OtherController具有所有或大部分相同的依赖项时,这种味道会更糟。我想重构它
我对DI的了解已经足够多,知道属性注入和服务定位器不是好主意
我不能分割我的主控制器,因为它是一个单一的屏幕,需要所有这些东西显示和编辑点击一个单一的保存按钮。换句话说,一个单一的post-action方法保存了所有内容(尽管如果有意义的话,我愿意更改它,只要它仍然是一个单一的保存按钮)。这个屏幕是用Knockoutjs构建的,如果有区别的话,可以用Ajax帖子保存
我幽默地使用了一个环境背景,但我不确定这是正确的方式。
我还幽默地使用了注入门面。
我还想知道我是否应该在这一点上实现一个命令体系结构。
(以上所有这些不都只是将气味转移到其他地方吗?)
最后,也许独立于上述三种方法,是不是应该使用一个,比如说,带有显式方法的LookupManager,比如GetAThings()、GetAThing(id)、GetBThings()、GetBThing(id)等等?(但是,LookupManager需要注入几个存储库,或者一种新类型的存储库。)
抛开我的思考,我的问题是,重申一下:重构代码以减少注入依赖项的数量的好方法是什么?您考虑过使用工作单元设计模式吗?关于什么是工作单位有一个帖子。那篇文章的摘录: 在某种程度上,你可以把工作单元看作是一个可以把所有东西都扔掉的地方 事务处理代码。工作单位的责任 将:
- 管理交易李>
- 对数据库的插入、删除和更新进行排序李>
- 防止重复更新。在工作单元对象的单一用法中,代码的不同部分可能会标记同一发票
对象已更改,但工作类的单位将只发出一个
对数据库执行单个更新命令
希望这有帮助 我认为您的主要问题是抽象层太多。您使用的是实体框架,因此您的数据周围已经有了一个抽象层,通过存储库和管理器接口又增加了两个层(每个实体一个),这导致了控制器所依赖的大量接口。它不会增加很多价值,而且 我将进行重构,去掉存储库和管理器层,并使用“环境上下文”
然后,查看控制器向管理器层询问的查询类型。在这些非常简单的地方,我发现直接在控制器中查询“环境上下文”没有问题——这就是我要做的。在更复杂的地方,将其重构为一个新的接口,在逻辑上对事物进行分组(不一定每个实体一个),并使用您的IOC进行分组。使用a是一个好主意,因为这样可以将所有业务逻辑移出控制器,并允许您在不更改代码的情况下添加。但是,这并不能解决您的问题。标准的解决方案是将相关的依赖项移动到一个新的应用程序中。但是,我同意Mark的观点,您应该看看。是工作单元模式的另一个变体。我是否只创建一个所有控制器都使用的Sungel UnitOfWork类?我已经有了一个总的记录。该类将引用每个存储库?是的,这正是它要做的。当从所有不同的回购协议中提取项目时,这个单元还将管理这些项目的并发性,并确保它们之间只有一个共享上下文。然后,我将得到一个带有构造函数的UnitOfWork类。看来无论发生什么我都需要聚合服务。可能重复感谢您的推荐。我喜欢这种方法。我将根据当前需要重构为聚合服务,然后深入研究命令体系结构和工作单元。@Steven您能否提供一个示例,说明如何使用SimpleInjector实现这一点。我一直在学习你的例子,这是一个有用的方法。我该如何应用门面服务或聚合服务。@DavidClarke:我不知道该显示什么。看看工作单元模式;这通常是一个包装存储库的类。为了防止工作单元中的构造函数过度注入,您可以注入一个知道如何解析存储库的工厂。@因此,在使用命令体系结构时,如何避免构造函数过度注入?似乎每个动作都需要至少一个处理程序和我的大部分同事