1

我正在使用 ASP.NET MVC 4、Entity Framework 和 C# 制作一个 Web 应用程序,并且我正在编写抽象超类来封装实体模型和视图模型。虽然细节并不重要,但我的问题是我希望这些抽象类实现从任何给定视图模型映射到相应实体模型的函数,反之亦然。

我实际上已经使用泛型和反射实现了这样的方法,但是我想让它更整洁。我通过这样定义 EntityModel 类来完成所有工作:

public abstract class EntityModel
{
    public TVM MapToViewModel<TVM, TEM>()
        where TVM : ViewModel<TEM>, new()
        where TEM : EntityModel, new()
    { (...) }
}

似乎没有必要将实体模型的类型作为参数发送,因为调用对象会知道它自己的类型,并让调用代码指定它会导致愚蠢的错误,但我不知道如何摆脱它。将方法定义为

public TVM MapToViewModel<TVM>()
    where TVM : ViewModel<EntityModel>, new()

看起来更整洁但它给出了编译时错误,因为 EntityModel 是抽象的。有没有办法告诉编译器它必须是 EntityModel 的派生而不是 EntityModel 本身?还是有其他更好的解决方案?

ViewModel<> 类非常相似,定义为:

public abstract class ViewModel<T>
    where T : EntityModel, new()

它正在按预期工作。

4

2 回答 2

3

考虑将映射功能移到实体和视图模型类之外。这将导致更适当的关注点分离,并消除您当前的通用签名问题。例如:

public abstract class EntityModel
{
}

public abstract class ViewModel<T>
    where T : EntityModel
{
}

public class ModelMapper<TEM, TVM>
    where TEM : EntityModel, new()
    where TVM : ViewModel<TEM>, new()
{
    public virtual TVM MapToViewModel(TEM entityModel)
    {
        // Default implementation using reflection.
    }

    public virtual TEM MapToEntityModel(TVM viewModel)
    {
        // Default implementation using reflection.
    }
}
于 2013-11-11T14:40:41.313 回答
1

妮可打败了我......只是想你可以有一个 FromEntity 代替,即:

public abstract class ViewModel<T>
    where T : EntityModel, new()
{
    public static ViewModel<T> FromEntity(T entity)
    {
        throw new NotImplementedException();
    }
}

public abstract class EntityModel
{
    //... properties, methods etc...
}

甚至让 ViewModel 在构造函数中使用 EntityModel

编辑

根据您的评论-是的,您是对的,我已将参数更改为 T 而不是 EntityModel。

这样做的好处是依赖来自 ViewModel > EntityModel 这应该是真的:)

于 2013-11-11T14:57:10.053 回答