管理多个相互依赖的模型

时间:2010-11-01 14:15:17

标签: c# winforms model-view-controller models

我正在尝试在基于消息传递的系统中管理多个模型。每个模型可能具有依赖于其他模型的值。例如:

   public class V2Model : BaseModel
   {
      private int mSomeVal;
      private byte mSomeByte;

      // …

      // Update mSomeByte based on multiple models values
      public void SetMultipleDependecyValue(int someIntFromModel1, short someShawteeyFromModel3)
      {
         mSomeByte = Convert.ToByte((someShawteeyFromModel3 / someIntFromModel1) + mSomeVal);
      }
   }

我还想使用MVC模式,但我没有传递Model实例,而是认为我会传入一个'Repository'实例。 “Repository”实例将充当处理所有Model实例的管理器。结果看起来像这样:

   public class V1Controller<ViewType, ModelType>
      where ViewType : IV1View
      where ModelType : BaseModel
   {
      ViewType mView;
      BaseRepository mBaseRep;

      public V1Controller(ViewType view, BaseRepository rep)
      {
         mView = view;
         mBaseRep = rep;
         mBaseRep.GetModel<ModelType>().PropertyChanged += new PropertyChangedEventHandler(V1ModelPropertyChanged);
      }

      void V1ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
      {
         switch (e.PropertyName)
         {
            case "SomeVal":
               // Update the view
               int some_val = mBaseRep.GetModel<ModelType>().SomeVal;
               mView.HexSomeValue = some_val;
               // Oh BTW, we know V2Model's value depends on this... update it with V1Model and V3Model's values
               short some_short = mBaseRep.GetModel<V3Model>().SomeShawteey;
               mBaseRep.GetModel<V2Model>().SetMultipleDependecyValue(some_val, some_short);
               break;
         }
      }

      public void UpdateVal(int someValue)
      {
         mBaseRep.GetModel<ModelType>().SomeVal = someValue;
      }
   }

在这种情况下,如果V1Model的属性发生了变化,在V1ModelPropertyChanged中,我会知道对V2Model对象的依赖性,并用适当的值更新它。有没有更好的方法来处理这种相互依赖的模型方案,或者这是一个可接受的解决方案?我并不是在寻找第三方。

2 个答案:

答案 0 :(得分:1)

如果你想优雅地处理这个问题,你需要让一些组件跟踪模型之间的依赖关系。当属性发生更改时,您将遍历该属性的所有依赖项,然后相应地更新它们。

也许您的BaseRepository可能会引用DependencyManager类。该类必须具有所有依赖于彼此的属性的列表。

一个简单的实现可能如下所示:

class PropertyDescriptor
{
    public Type ModelType { get; set; }
    public string Property { get; set; }
}

class DependencyManager
{
    private Dictionary<PropertyDescriptor, List<PropertyDescriptor>> _dependencies = new Dictionary<PropertyDescriptor, List<PropertyDescriptor>>();

    public void RegisterDependency(PropertyDescriptor property, PropertyDescriptor dependentProperty)
    {
        if (!_dependencies.ContainsKey(property))
        {
            _dependencies.Add(property, new List<PropertyDescriptor>());
        }
        _dependencies[property].Add(dependentProperty);
    }

    public IEnumerable<PropertyDescriptor> GetDependentProperties(PropertyDescriptor property)
    {
        if (!_dependencies.ContainsKey(property))
        {
            yield break;
        }
        else
        {
            foreach (PropertyDescriptor p in _dependencies[property])
            {
                yield return p;
            }
         }
     }
}

然后,当您检测到属性更改时,可以查询DependencyManager以了解还需要更改的内容。但是在级联时要小心检查循环依赖性!

答案 1 :(得分:1)

也许我错过了什么,但这不是observer pattern的意思吗?如果将模型设置为彼此的观察者(即,使用委托或事件),那么控制器应该能够保持对依赖性的无知。