寻找模式来组合来自不同组件的部分类

时间:2011-07-18 13:09:17

标签: c# .net design-patterns

我遇到以下问题。我有一个主项目,以及一些具有类似功能的额外项目。

例如:我有一个MVC网站,然后是一个带有“SettingsHelper”的类库项目“A”。这只是为配置设置定义静态包装器,因此它们可以用作属性。

然后我有另一个类库项目“B”,包含“SettingsHelper类”。

如何在主项目中合并这些SettingsHelpers,因此我可以使用:来自两个模块化额外项目的SettingsHelper.Property。

我希望能够将额外的类库插入一个项目中。

5 个答案:

答案 0 :(得分:2)

那不行。部分类不能通过程序集进行划分 - 它们不存在于CLR中,仅存在于编辑器和编译器中。所以它们被编译成一个CLR类。

你能做什么,是从另一个继承。但是,帮助程序往往是静态类,因此也不起作用。

另一种选择不是编写辅助类,而是编写扩展方法。您可以使用另一个程序集(或多个其他程序集)中定义的方法在一个程序集中扩展类。另请参阅http://msdn.microsoft.com/en-us/library/bb383977.aspx

答案 1 :(得分:1)

听起来非常像依赖注入。通常,您会将SettingsHelper公开为接口(您的合同),并针对该程序进行编程。然后,DI容器(如Ninject,StructureMap或Windsor)会根据配置将该接口的实现插入代码的相关部分。

这将允许您根据具体情况对已知合同进行编码并提供不同的库,然后DI框架可以使用该库来获取接口的具体实现。

您是否需要同时使用这两个实例?

请注意,您不能在不同的程序集中使用partial关键字,只能在程序集中使用。

更新:根据你的评论听起来你想做像Composition这样的事情。有一个类从两个库中获取两个类,并将它们组合成一个可供应用程序使用的类。无论您是将其配置为执行某些特殊操作还是在存在库时加载类型,都可以将其封装在此新类中。

更新2:或者,查看MEF:

http://msdn.microsoft.com/en-us/library/dd460648.aspx

答案 2 :(得分:0)

我想说在第三个项目中移动两个Helper 类,并将那个项目的引用添加到您的两个项目中。因此,这个新库将成为共享数据结构和功能库

问候。

答案 3 :(得分:0)

您所追求的特定模式称为Facade Pattern。不幸的是,你不会得到编译器得到任何帮助。基本上:

  1. 在本地程序集中创建一个新的CombinedSettingsHelper类。
  2. 如果两个SettingsHelper类型位于同一名称空间中,则需要为它们设置别名(请检查解决方案资源管理器中的引用属性,并MSDN documentation为此)。
  3. 实现对象,以便它可以访问SettingsHelper个对象。
  4. 要清理外观,您可以尝试使用abstract object GetSettingValue(string name);的抽象方法。然后,您的外观可以从相同的基类继承,并在其包含的子项上调用它们。例如:

    public abstract class SettingsHelperBase { public object GetSettingValue(string settingName); }
    
    // Assembly1
    public class SettingsHelper : SettingsHelperBase { }
    
    // Assembly2
    public class SettingsHelper : SettingsHelperBase { }
    
    public class SettingsHelper : SettingsHelperBase
    {
        private List<SettingsHelperBase> _backends = new List<SettingsHelperBase>();
    
        public readonly PropertiesImpl Properties;
        public class PropertiesImpl
        {
            private SettingsHelper _settingsHelper;
            public string Name
            {
                get
                {
                    return (string)_settingsHelper.GetSettingValue("Name");
                }
            }
    
            internal PropertiesImpl(SettingsHelper helper)
            {
                _settingsHelper = helper;
            }
        }
    
        public SettingsHelper()
        {
            _backends.Add(asm1::MyNs.SettingsHelper);
            _backends.Add(asm2::MyNs.SettingsHelper);
            Properties = new PropertiesImpl(this);
        }
    
        protected override object GetSettingValue(string settingName)
        {
            foreach (var item in _backends)
            {
                var val = item.GetSettingValue(settingName);
                if (val != null)
                    return val;
            }
            return null;
        }
    }
    

答案 4 :(得分:0)

有办法; Visual Studio允许相同的代码文件包含在多个项目中。

当您执行“添加”/“现有项目”时,可以选择不同文件夹中的文件。

这是一些银光支持所做的,以便允许“公共类”具有仅在服务器上的一些方法和仅在客户端上的一种方法。

(关于“好设计”的问题,你必须自己决定,很多人不喜欢在不同的项目中以不同的方式编写同一个类。想想你是否可以使用#if XXX,当XXX仅在其中一个项目中定义时)