Ich kam auf zwei Ansätze dazu.
Die erste war Code zu meiner NHibernate Repository-Klasse hinzufügen, um den einfachen POCO-Typen von dem MVC-Controller verwendet, zu übersetzen, um die Art der Einheit ( SimpleThing), die NHibernate (RealThing) wollte:
/// <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;
}
}
So kann jede Methode im Repository GetKnownEntity (T-Element) aufrufen und die Eigenschaften des übergebenen Elements in den Typ kopieren, den NHibernate möchte. Offensichtlich fühlte sich das ein wenig klobig an, also schaute ich mich nach maßgefertigten Modellbindern um.
Im zweiten Ansatz, habe ich ein benutzerdefiniertes Modell Bindemittel wie folgt aus:
public class FactoryModelBinder<T>
: DefaultModelBinder
where T : new()
{
protected override object CreateModel(ControllerContext controllerContext,
ModelBindingContext bindingContext,
Type modelType) {
return new T();
}
}
Dann habe ich registriert, dass in Global.asax.cs mit:
ModelBinders.Binders.Add(typeof(IThing),
new FactoryModelBinder<RealThing>());
Und es funktioniert gut mit einer Controller-Aktion, die wie folgt aussieht:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
// code to process the thing goes here
}
Ich mag den zweiten Ansatz, aber die meisten meiner Abhängigkeitsinjektion Zeug ist in der Controller-Klasse. Ich möchte nicht alle diese ModelBinder-Zuordnungen in Global.asax.cs hinzufügen müssen.
Hallo user10789, hast du dieses schnelle Kopfgeld gesetzt? –