让我们说我有这样的接口:

interface IThing {
   int Id { get; set; }
   string Title { get; set; }
}

和在ASP.NET MVC我有一个形式职位,以像这样的控制器动作:

 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult NewThing([Bind(Exclude = "Id")] SimpleThing thing) {

    // code to validate and persist the thing can go here            
 }

其中 SimpleThing 是一个具体的类,它只是勉强器具 IThing

不过,我想我所有的方法来处理的接口。我有一个使用NHiberate和它自己的数据汇编的 IThing 的实现(我们称之为的 RealThing 的)。我不能通过SimpleThing它,因为它会抱怨“未知实体”。

有没有人有关于一个更清洁的方式做到这一点任何想法?我在想沿着使用工厂类的东西线。但我怎么会得到MVC形式粘结剂使用它?

谢谢!

有帮助吗?

解决方案 3

有一些好的建议在这里,我确实有一个可行的解决方案上来。不过,我结束了一些完全。我刚刚创建特定的表单数据我张贴的模型和使用默认的模型粘合剂。

更简单,它可以让我捕捉到的数据,是不是我的域模型的一部分(即像“意见”字段)。

其他提示

您可以使用自定义模型粘合剂的。但是MSDN上的文章是完全无用的。所以,最好是采用搜索并找到更好的东西。有可用的物品planaty。

我想出了两种方法来此。

首先是将代码添加到我的NHibernate的存储库类翻译由MVC控制器使用的简单POCO类型( SimpleThing )到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项),它会复制项的属性你在传递给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的映射。

这是不dirrect unswer你的问题。

我们使用略有不同的方法来对付你有同样的问题。我们的控制器接受由字段相匹配的持久化实体字段的DTO。然后,我们的用户 AutoMapper 创建persisten实体会到数据库中。这消除unnessesery接口和锁定了面向公众的API(意味着重命名持久性对象的字段不会破坏我们的客户端代码)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top