如何在C#中构建混合架构框架?

时间:2010-12-01 17:39:29

标签: c# frameworks mixins

我有一个我想要构建的控件框架的概念。使这个想法与众不同的是,我不打算采用“一刀切”的方法或“一个控制来统治所有人”的方法。

作为一个例子,Telerik做了一个非常好的网格控件,ComponentOne,Xceed等也是如此。但是,它们都是巨大的控件,有数百或数千种方法和属性,复杂的对象模型层次结构等等...这些网格往往对你所需要的东西有点过分,但你仍然需要承担学习整个网格的艰巨任务来做一些简单的事情。

我的概念更像是一种“混合”的方式。在哪里创建一个非常简单的控件,然后构建可以“加载”到控件点菜的功能。例如,您有一个简单的网格,并且您希望为每个网格添加带有页眉和页脚的网格“部分”。

好的,问题出在哪里?做这样的事情的传统方式是通过多重继承,C#不支持。即使它确实支持它,我仍然认为MI增加了比它解决的问题更多的问题。

因此,我正在征求SO的意见,以了解如何解决这个问题。 MEF会成为潜在的解决方案吗?

编辑:

我遇到的一点是,可以使用表达式树从各种表达式构建控件。我不得不考虑更多,但这是一个有趣的概念。

另一个可能的选项可能是“控制生成器”,它根据所选功能生成一个程序集。这似乎更复杂,但T4可能是可管理的。

6 个答案:

答案 0 :(得分:3)

一些选项

  1. 考虑装饰者模式;小对象,它们可以扩展在运行时可以构建的相当极简的类的行为。 Dotnet框架中的规范示例将围绕IO流(例如StreamReader / Writer,TextStreamReader / Writer,FileStreamReader / Writer);在OO UI框架中也很常见,典型示例看起来像var window=new HorizontalScrollingWindowDecorator(new VerticalScrollingWindowDecorator(new Window));

  2. 状态,策略,命令和复合模式为处理行为组合提供了各种替代方案,而无需大量控制流程。例如,您将某些类型的行为委托给对象的当前状态(您的一些类方法基本上调用当前对象State的方法)。您还可以将行为委派给命令对象,或使用复合命令构建复杂命令。单继承通常会引导您支持对象的组合而不是继承,这些都是用于组合行为的经典模式,这些模式适用于单继承。

  3. 当特定实例需要实现一些小的行为时,您可以使用委托作为函数式编程中常见的“中间漏洞”模式。

  4. 您可以使用PostSharp或类似的面向方面的编程工具来执行运行时或编译时的行为编织,尤其适用于几个不同类的行为所需的行为,这些行为与该课程的主要责任。

答案 1 :(得分:2)

就我个人而言,我认为多重继承对于实现这种设计来说是一种糟糕的方式。似乎多数继承在大多数时候都是一个糟糕的设计。继承是组件之间关系的僵化。

组合更加灵活,在这种情况下,MEF将是一个非常好的起点。

控件的基类将是行为的容器 - 本质上是MEF容器。

它仍然存在其他类如何与控件交互的问题。有很多选择。例如基本控件上的标准接口,消息传递,甚至在C#4.0中使用动态绑定。

答案 2 :(得分:1)

我想尝试回答,而不是评论这是否值得解决。

我没有尝试过这个组件,但理论上有Decorator Pattern:您可以在运行时添加插件来拦截控件(键盘和鼠标)输入和(屏幕)输出。

答案 3 :(得分:1)

WPF通过允许您将逻辑元素的可视表示与数据模板合成来解决此问题。 Control类本身不是混合使用功能来创建一个新的Control类,而是通过结合各种类型的内容来提供可扩展性点,并使用丰富的模板系统来安排和可视化内容。

换句话说,仍然可以说是“一个控制来统治它们”,但控制是一个骨架,而不是一个完全充实的身体。脚手架提供了一个易于理解的框架,在其中添加功能,模板系统提供了用于充实控件部件的粘合剂。


关于MEF,MEF购买的是发现和注入扩展代码。它很有价值,但并没有直接解决你所描述的问题。您的问题与代码的发现关系不大,更多的是与代码组合的机制有关,以创建一致的整体控件。 MEF可以帮助执行一些胶合,但它只是问题的一小部分。

答案 4 :(得分:0)

您是否想构建一个Add-In类型的框架?我肯定会指向Managed Extensibility Framework。可以在.Net 4.0中使用WinForms或WPF。

答案 5 :(得分:0)

如果您对已经实现了mixin的框架感兴趣,请查看re-motion框架(https://www.re-motion.org/)。令人惊讶的是,mixins在这个框架中可以轻松实现,

以下是“Hello World”级别的参考申请。

使用从webseite下载的程序集,在VS2010中创建一个类库和一个控制台应用程序,在这两个项目中添加对assmblies remotion.dll和remotion.interfaces.dll的引用。

using System;

namespace Domain
{
  public class Person
  {
    public Person()
    {
    }
    public Person(Person person)
    {
      FirstName = person.FirstName;
      LastName = person.LastName;
      BirthDay = person.BirthDay;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDay { get; set; }
  }
}



using System;
using Remotion.Mixins;

namespace Domain
{
  public interface IEmployeeMixin
  {
    int Salary { get; set; }
    DateTime? HireDate { get; set; }
  }

  [Extends(typeof(Person))]
  public class EmployeeMixin : IEmployeeMixin
  {
    public int Salary { get; set;  }
    public DateTime? HireDate { get; set;}
    public EmployeeMixin()
    {
      // set default values
      Salary = 1000;
      HireDate = DateTime.Now;
    }
  }
}



using Domain;
using Remotion.Reflection;
using Remotion.Mixins;

namespace ConsoleApp
{
  class Program
  {
    static void Main(string[] args)
    {
      Person p = new Person();
      p.FirstName = "John";
      p.LastName = "Doe";

      var employee = (IEmployeeMixin)ObjectFactory.Create<Person>(ParamList.Create(p));

      System.Console.WriteLine("Fullname: {0}", ((Person)employee).FirstName + " " + ((Person)employee).LastName);
      System.Console.WriteLine("Salary: {0}", employee.Salary);

      System.Console.ReadKey();
    }
  }
}

基于这个参考实现,应该很容易理解,这个mixin是如何在这个框架中实现的。如果您想获得有关此框架(它是一个完整的DDD开发框架)或mixins的更多信息,请不要犹豫。我可以为您提供更多文档。

的Stefan