【发布时间】:2011-07-01 12:19:35
【问题描述】:
我希望了解 Ioc/Di 如何简化我经常使用的以下类的布线。
考虑一个库,它具有实体的抽象概念和数据访问对象的接口:
public abstract class EntityWithTypedId<TId> : IEntityWithTypedId<TId>{...}
public interface IDao<T, TId> where T : IEntityWithTypedId<TId>
对于 dao,我有一个 NHibernate 实现以及一个我认为对测试有用的假 dao:
// has an NHib implementation
public class Dao<T, TId> : IDao<T, TId> where T : EntityWithTypedId<TId> {...}
public class DaoFakeBase<T> : IDao<T, int>, IDisposable where T : IEntityWithTypedId<int> {...}
我目前执行以下操作来为给定项目定义 Entity 和 Dao 类型:
/// <summary>
/// <see cref="IEntityWithTypedId{IdT}"/> with an int for an id
/// </summary>
[Serializable]
public abstract class Entity : EntityWithTypedId<int>
{
}
public class Dao<T> : Dao<T, int> where T : Entity
{
protected Dao(ISessionFactory sessionFactory) : base(sessionFactory) { }
}
我可以改用 DI 工具来定义实体吗?如果是这样,有人可以向我展示如何执行此操作的代码示例吗?
您能否也列出我如何告诉我的测试程序集使用 DaoFakes 和生产使用 NHib.Dao
我一直在关注 Windsor,主要是因为 NHibernate contrib 项目使用它,但我也对 MEF、AutoFac 和 Ninject 感兴趣,按此顺序排列。我意识到 MEF 不是 Windsor 意义上的 IoC 容器。从我在 Windsor 中看到的情况来看,我会使用 Installer 类,可能是 EntityInstaller 和 DaoInstaller,尽管我也可能在这里遗漏了一个 FActory 类型的对象。
干杯,
浆果
更新@KeithS
你是说要改变类似的东西:
class MyViewModel(IDao<MyClass, int> dao) {...}
变成类似
class MyViewModel(Func<IDao<MyClass, int>, obj> getDaoFunc) {
_dao = getDaoFunc(this);
}
【问题讨论】:
-
您没有列出 Prism/Unity,所以我不会将其添加为正式答案...但是归结为简单地注册具有具体类型的接口。如果您愿意,可以将定义包装在 #if debug 中; IUnityContainer.RegisterType
();因此在运行时 IFileManager 的所有解析都将解析为 FileManager 类型。 -
@Aaron 这不是违背了使用接口的目的吗?
-
@Brian No...这是整个应用程序中唯一引用具体类型的行。其他任何地方都在不了解实现细节的情况下引用该接口。在每个模块中(由 Prism 调用)都有一个 init 方法,在该方法中进行注册……如上所示,这是一个单行。
-
@Aaron 谢谢;我不熟悉 Prism/Unity 因此我的问题。
-
通过委托解析类型实际上比简单地将类型的实例注入构造函数有点“混乱”。无论哪种方式,你都可以做到。实例注入总体上更简单。委托注入允许对您不需要的对象进行延迟实例化,或者甚至根本不需要(如果您的对象可以在没有依赖关系的情况下执行一些常见任务)。方法注入可以减少初始加载时间,但会在您真正需要它时弥补该时间(但可能不会实例化一堆其他东西)。
标签: c# dependency-injection castle-windsor ioc-container mef