【问题标题】:ViewModel many to many relationshipViewModel 多对多关系
【发布时间】:2012-03-05 17:52:56
【问题描述】:

对于我们的项目,我们想使用 ViewModels。 所以我们决定为我们可以拥有的每个对象创建 ViewModel:

所以 ViewModel 看起来像这样(GroupVM):

public class GroupVM : EORTCViewModel<Prisma.BO.Group>
{
    public GroupVM(Prisma.BO.Group group) : base(group) { }

    public string Name
    {
        get
        {
            return this._Model.Name;
        }
    }
    public string ShortName
    {
        get
        {
            return this._Model.ShortName;
        }
    }

    public int Id
    {
        get
        {
            return this._Model.Id;
        }
    }

    [ScriptIgnore]
    public ICollection<StudyGroupVM> StudyGroups
    {
        get
        {
            return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.StudyGroup>.ToViewModel<StudyGroupVM>(this._Model.StudyGroups);
        }
    }
}

StudyVM:

public class StudyVM : EORTCViewModel<Prisma.BO.Study>
{
    public StudyVM(Prisma.BO.Study study) : base(study) { }

    public string Number
    {
        get
        {
            return this._Model.Number;
        }
    }

    [ScriptIgnore]
    public ICollection<StudyGroupVM> StudyGroups
    {
        get
        {
            return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.StudyGroup>.ToViewModel<StudyGroupVM>(this._Model.StudyGroups);
        }
    }
}

和中间对象(StudyGroup):

public class StudyGroupVM : EORTCViewModel<Prisma.BO.StudyGroup>
{
    public StudyGroupVM(Prisma.BO.StudyGroup studyGroup) : base(studyGroup) { }

    public StudyVM Study
    {
        get
        {
            return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.Study>.ToViewModel<StudyVM>(this._Model.Study);
        }
    }

    public GroupVM Group
    {
        get
        {
            return Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.Group>.ToViewModel<GroupVM>(this._Model.Group);
        }
    }
}

我们想使用一个工厂来为每个导航属性创建 ViewModel。

所以我们写了一个通用的 ViewModel 工厂如下:

public static class ViewModelFactory<T> where T : IEORTCObject
{
    public static R ToViewModel<R>(T model) where R : EORTCViewModel<T>
    {
        return (R)Activator.CreateInstance(typeof(R), new object[] { model });
    }

    public static ICollection<R> ToViewModel<R>(ICollection<T> models) where R : EORTCViewModel<T>
    {
        ICollection<R> viewModels = new List<R>();
        foreach (T model in models)
        {
            viewModels.Add((R)Activator.CreateInstance(typeof(R), new object[] { model }));
        }
        return viewModels;
    }
}

问题在于,当我们尝试从关系的最终对象之一访问 StudyGroups 属性时,它会正确创建该对象,但随后又想重新创建相同的对象,因为它似乎试图访问另一个对象的 getter关系结束。

这会导致 StackOverFlowException,因为它永远不会停止(循环)。

你们中有人知道我该如何解决这个问题吗?

【问题讨论】:

  • 我只能说 Activator.CreateInstance 不是一个好的 IOC 容器!

标签: c# generics viewmodel


【解决方案1】:

您可以在创建一次后使用 memoization 缓存您的视图模型吗?

类似:

public GroupVM Group
{
    get
    {
       if(groupVM == null)
       {
             groupVM = Prisma.Web.Models.Factories.ViewModelFactory<Prisma.BO.Group>.ToViewModel<GroupVM>(this._Model.Group);
        }
        return groupVM;
    }
}

【讨论】:

  • 是的,但是我需要一个容器来保存已经创建的每个视图模型的引用。但事实上,我可以做到。
  • 任何其他想法,因为如果我们使用它,我们需要进行大量检查才能知道何时创建新实例,因为完整的模型非常大。
  • 为什么需要使用视图模型?
  • 由于我们使用 Telerik MVC Extension GridView,并且那些需要 JSON 才能与 ajax 绑定正常工作,我们希望能够将 BO 转换为 JSON。 JSON 序列化程序在尝试转换 BO 时会抛出一些异常。但我当然愿意接受其他所有可能性。
  • 您可以尝试使用 AutoMapper 之类的东西来创建您的 ViewModel。它可能会处理您的循环引用,但我已经好几年没有使用它了
猜你喜欢
  • 2023-02-24
  • 2019-05-24
  • 1970-01-01
  • 2018-06-15
  • 1970-01-01
  • 2014-10-11
相关资源
最近更新 更多