我想出了两种方法。
第一个是将代码添加到我的 NHibernate Repository 类中,以将 MVC 控制器 ( SimpleThing ) 使用的简单 POCO 类型转换为 NHibernate 想要的实体类型 ( RealThing ):
/// <summary>
/// A NHibernate generic repository. Provides base of common
/// methods to retrieve and update data.
/// </summary>
/// <typeparam name="T">The base type to expose
/// repository methods for.</typeparam>
/// <typeparam name="K">The concrete type used by NHibernate</typeparam>
public class NHRepositoryBase<T, K>
: IRepository<T>
where T : class
where K : T, new()
{
// repository methods ...
/// <summary>
/// Return T item as a type of K, converting it if necessary
/// </summary>
protected static K GetKnownEntity(T item) {
if (typeof(T) != typeof(K)) {
K knownEntity = new K();
foreach (var prop in typeof(T).GetProperties()) {
object value = prop.GetValue(item, null);
prop.SetValue(knownEntity, value, null);
}
return knownEntity;
} else {
return (K)item;
}
}
因此,存储库中的任何方法都可以调用 GetKnownEntity(T item),它会将您传入的项目的属性复制到 NHibernate 想要的类型。显然这感觉有点笨拙,所以我研究了自定义模型活页夹。
在第二种方法中,我创建了一个自定义模型绑定器,如下所示:
public class FactoryModelBinder<T>
: DefaultModelBinder
where T : new()
{
protected override object CreateModel(ControllerContext controllerContext,
ModelBindingContext bindingContext,
Type modelType) {
return new T();
}
}
然后我在 Global.asax.cs 中注册了它:
ModelBinders.Binders.Add(typeof(IThing),
new FactoryModelBinder<RealThing>());
它适用于如下所示的控制器操作:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
// code to process the thing goes here
}
我喜欢第二种方法,但我的大部分依赖注入东西都在 Controller 类中。我不想在 Global.asax.cs 中添加所有这些 ModelBinder 映射。