我现在看到改造一个’brownfield’c#项目使用autofac是多么可行.该项目需要创建一个不同类型但具有相同基类的组件树.这些组件需要身份验证和数据库服务(以及其他内容),因此很难只拥有空构造函数.
因此,工厂可以创建导出基类的对象,使用autofac扫描这些类,并为它们提供工厂.我认为如果你不必为每个类提供工厂,它可能会更容易构建组件对象树.
除此之外,还是这是一个糟糕设计的标志?组件和树应该尽可能少地执行,我们将此树传递给其他服务以提供处理和呈现吗?
像(哪里?是神秘工厂)的东西
public MyBase { public Add(MyBase x) {..} } public DerivedA: MyBase {} public DerivedB : MyBase {} public DerivedC : DerivedA {} public SomethingElse { private ? _myBaseFact; public SomethingElse(? myBaseFact) { _myBaseFact = myBaseFact; } public BuildComponentTree() { DerivedA a = _myBaseFact<DerivedA>(); DerivedB b = _myBaseFact<DerivedB>(); DerivedC c = _myBaseFact<DerivedC>(); a.Add(b); b.Add(c); } }
编辑:我被要求一个更具体的例子,这是公平的:)有框架组件,我想允许开发人员创建自己的组件,而无需注册autofac.拥有工厂类意味着开发人员必须将自定义组件添加到此工厂吗?请原谅这个例子,这与我遇到它时框架的工作原理类似.
FwComponent { public FwComponent (DataProvider,AuthManager,OtherModule) public Add(FwComponent x); public Setup(); public Process(); public Render(); } Page : FwComponent { public Page(DataProvider,OtherModule): base(..) public string Title; ... } Input: FwComponent { public Input(DataProvider,OtherModule): base(..) public string Name; public int length; ... } Button: FwComponent { public Button(DataProvider,OtherModule): base(..) public string Name; ... } ---- MyCustomButton : Button { public MyCustomButton(DataProvider,OtherModule): base(..) } MyPersonalPage : FwComponent { IContext _container; public MyPersonalPage(DataProvider,OtherModule,IContext container): base(..) public Setup() { var input = _container.Resolve<Input>(); input.Name = 'xxx'; input.length = 10; Add(input); var butt = _container.Resolve<MyCustomButton>(); butt.name = "xxx"; Add(butt); } public Process() { DataProvider.DoStuff(); } }
解决方法
在我看来,你有两个选择:你注入一个工厂并抽象出派生类型,或者你直接将派生类型注入构造函数.使用工厂在两个场景中很有用:
1:您有某种(不是基于类型的)参数,允许工厂识别返回的类型,如以下示例所示:
public class MyBaseFactory : IMyBaseFactory { public MyBase CreateMyBase(IUserContext user) { // Create a MyBase based on a user object. } }
2:您的工厂有多种工厂方法:
public class MyBaseFactory : IMyBaseFactory { private Autofac.IContainer container; public MyBase CreateMyBaseForScenarioA() { return container.Resolve<DerivedA>(); } public MyBase CreateMyBaseForScenarioB() { return container.Resolve<DerivedB>(); } }
请注意,两个工厂方法都返回MyBase,而不是特定类型.关于多态的整个想法是你不应该关心具体类型.
IMO无论Autofac是否可以为您创建工厂都无关紧要.您不应该依赖于类似于框架的结构,而是依赖于良好的应用程序设计.如果您采用工厂方法,请为该工厂定义接口并根据该接口注入实例.这使得设计非常干净,并且非常好地传达了它的意图.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。