2

我的团队正试图找出在我们的自定义程序集中管理集中常量(可能是只读静态变量)的最佳方法。我们构建了一个处理架构,其中程序集被动态加载到运行时中。当数据通过我们的系统时,一些程序集将信息写入字典,然后将其传递给另一个程序集,该程序集将读取数据并对其进行处理。随着我们产品的成熟和我们的客户需要不同的处理能力,我们将需要添加将被写入/读取的新数据字段。到目前为止,我们已经在核心 dll 中定义了常量,但这不会长期有效,因为当我们获得一条新数据时,我们将不得不重新编译核心 dll,在这样做的过程中,我们的测试团队将不得不对整个应用程序进行全面的回归测试,而不仅仅是测试新程序集提供的新功能。试图找出一种方法来添加新常量并知道正在写入什么数据,而无需重新编译/部署我们绝对不需要的任何东西。

我们考虑了两种选择:

  1. 创建一个常量 dll,它只保存常量。当我们需要新字段时,我们将它们添加(从不删除)到 dll 中。不利的一面是对 dll 的更改仍然会影响整个系统,因此可能需要进行完整的回归测试。

  2. 让每个程序集公开它读取/写入的所有字段,然后在开发人员集成期间查找名称不匹配。例如,Assembly1 写入 (Field1, Field2),Assembly2 读取 (field1, Filed2),由于字典键区分大小写,导致 (Field1 与 field1) 不匹配。这将阻止我们使用常量程序集,但它需要一些额外的代码来验证不匹配,并且似乎会导致一些耦合。

注意:当我说常量时,我​​并不是说常量。根据我们最终使用的解决方案,我们可能会使用只读静态。

如果有人做过这样的事情,或者对实现这一点的方法有任何想法,我将不胜感激您的意见。我们的基本目标是能够通过仅部署新程序集来提供新功能。

4

2 回答 2

0

Based on your comment, this really sounds like you should be using DTO classes. Rather than a dictionary with values

dict["PrimaryAddress"] = "123 Someroad St."; 
dict["Name"] = "John Doe";`

you should have an object

public class Address
{
    public string PrimaryAddress { get; set; }
    public string Name { get; set; }
}
....
new Address { 
    PrimaryAddress = "123 Someroad St.",
    Name = "John Doe",
};

For convenience, you can create a base class in your core library which defines some standard behavior for all the classes (for example, public Dictionary<string, string> ConvertToDictionary() for legacy use), and then each assembly can inherit from that to create their own objects. Then the assembly that consumes them can either reference the generating assembly and treat it as the specific type, or it can just treat it as the base form and use the base functionality.

于 2012-11-14T15:41:06.770 回答
0

您可以做的是创建一个被整个流程中的所有其他程序集引用的程序集。(请注意,我假设您的应用程序中实际上只有一个进程)。这个程序集将公开一个类来保存这些“常量”。让我们称之为会话。这是我们在一个项目中使用的实现:

//Defined in Dll appshared.dll    
public static class MyApplication
{
    static AppSession appSession = new AppSession();
    public interface IAppSession
    {
        Object this[string key]
        {
            get;
            set;
        }
    };
    sealed class AppSession : IAppSession
    {

        Dictionary<String, Object> _session = new Dictionary<string, object>();
        public AppSession()
        {
        }
        public Object this[string key]
        {
            get
            {
                Object ret = null;
                lock (_session)
                {
                    _session.TryGetValue(key, out ret);
                }
                return ret;
            }
            set
            {
                if (key == null)
                    throw new ArgumentNullException();
                try
                {
                    lock (_session)
                    {
                        if (value != null)
                            _session[key] = value;
                        else
                            _session.Remove(key);
                    }
                }
                catch (Exception eX)
                {
                }
            }
        }
    };

    public static IAppSession Session
    {
        get
        {
            return appSession;
        }
    }

};

您可以按如下方式使用它:

//In Dll A referencing appshared.dll   
MyApplication.Session["Const1"] = 1.0;//Set a global value

//In Dll B referencing appshared.dll    
double const1 = (double)MyApplication["Const1"];//Read a global value - const1 will have the value set by Dll A

//In Dll C referencing appshared.dll
MyApplication.Session["Const1"] = null;//Delete a global value;

您当然可以存储您想要的任何类型的数据。您可以轻松地将其修改为不区分大小写。

我们还有一个更复杂的会话对象,它可以将值与配置文件同步,因此“常量”可以跨执行存储。但是,由于您没有提到您需要这种能力,所以这个简单的类应该对您很好。

于 2012-11-14T16:26:59.737 回答