帮助需要添加新的方法,属性分为动态现有类(Help required in adding new m

2019-11-03 17:32发布

我不知道是否有可能实现这种在斑点网实现的。 下面是信息

目前,我们在其上的COM +,ASP,XSL,XML技术完成的应用程序。 它是一个多层体系结构的应用,其中COM +充当BAL。 对于任何CRUD动作的执行步骤将利用使用XML来存储的信息的单独的UI来定义。 BAL读取XML并理解这些定义的执行步骤和执行DLL对应的方法。 就像EDM我们有我们的客户定制模型(使用XML),它确定物体的属性进行搜索,检索等。基于此信息BAL构造查询和调用程序,以获取数据。

在当前的应用程序都BAL和DAL都没有做任何代码更改大量定制。 结果会在其中构建了基于收到数据的UI的XML格式被发送到表示层。

现在,我创建一个迁移项目与员工信息的交易。 它也将跟着N个层架构中的表示层与BAL通信,它连接到DAL返回数据。

这里的问题是,在我们现有的版本中,我们正在处理每一个信息的天然形式(无对象等converstion)XML,但在迁移项目,团队是在利用开发的面向对象的模型,每一个信息是真的有兴趣从BAL发送需要被转换到其相应类型的对象(例如employeeCollection,地址集合等)。

如果我们从BAL我们回到可以有一个包含这些节点的属性的类数据的静态数量,我们可以访问相同的。 但在我们的情况下,从我们的BAL需要定制返回的数据。 我们该如何处理其中的结果转换为对象表示层的定制。

下面是返回的XML的例子

<employees>
    <employee>
        <firstName>Employee 1 First Name</firstName>
        <lastName>Employee 1 Last Name</lastName>
        <addresses>
            <address>
                <addressType>1</addressType>
                <StreetName>Street name1</StreetName>
                <RegionName>Region name</RegionName>
            <address>
            <address>
                <addressType>2</addressType>
                <StreetName>Street name2</StreetName>
                <RegionName>Region name</RegionName>
            <address>
            <address>
                <addressType>3</addressType>
                <StreetName>Street name3</StreetName>
                <RegionName>Region name</RegionName>
            <address>
        <addresses>
    </employee>
    <employee>
        <firstName>Employee 2 First Name</firstName>
        <lastName>Employee 2 Last Name</lastName>
        <addresses>
            <address>
                <addressType>1</addressType>
                <StreetName>Street name1</StreetName>
                <RegionName>Region name</RegionName>
            <address>
            <address>
                <addressType>2</addressType>
                <StreetName>Street name2</StreetName>
                <RegionName>Region name</RegionName>
            <address>
        <addresses>
    </employee>
</employees>

如果这是唯一的列的话,我可以写一类是像

public class Address{
    public int AddressType {get;set;};
    public string StreetName {get;set;};
    public string RegionName {get;set;};
}

public class Employee{
    public string  FirstName {get; set;}
    public string  LastName {get; set;}
    public string  AddressCollection {get; set;}
}

public class EmployeeCollection : List<Employee>{
    public bool Add (Employee Data){
    ....
    }
}

public class AddressCollection : List<Address>{
    public bool Add (Address Data){
    ....
    }
}

这个类将提供给客户和顾问的DLL文件。 我们不会提供相同的源代码。

现在,当顾问或客户确实定制(例如添加国家来解决,增加护照信息的对象与员工的对象),它们必须能够在这些类来访问这些属性,但没有源代码,他们将不能够做那些modifications.which使应用程序形同虚设。 有没有什么办法在DOTNET的到acomplish这一点。

我想用匿名类的,但是,与匿名类的问题是

我们不能在它的方法。 我不知道我怎样才能适应集合对象(这将是inturn一个匿名类)不知道有关的DataGrid /用户控制结合等。

我也想过用的CodeDOM创建类运行,但不能确定meory,性能问题。 同样的类必须创建只有一次,直到有另一个变化必须使用相同的。

请帮我出这个问题。 任何种类的帮助材质/神秘代码/链接会有所帮助。

更新:

感谢您所提供的答案,这让我寻找到我没有想到的不同区域。

有信息我错过了问题的一个peice的。 UI代码也将因为DLL文件而不是源代码。 顾客可以自由地创建新的代码,并连接到用户界面,但他们无法通过代码更改现有的用户界面。 我们有一个设计者,其将显示可选择的,可显示特性从该顾客可以选择数据显示给用户。 这样,他们可以改变用户界面的外观和感觉。 此外,他们可以更改使用这种模式的绑定属性。

如果我在这个问题给出的这片我也许能得到一些答案,并可能给你究竟是发生了一个清晰的概念。

通过上述一块,下面是我的新思维

我还想到使用的CodeDOM模型seperately创建类并迁移到相同的用户界面的东西。 下面是我的想法

创建控制台应用程序读取我们的结构的XML文件。 它将包含在系统中可用的属性和类。 还创建一个用户界面来操作XML文件来创建类。 在控制台中使用的CodeDOM生成的类和方法。 使用库或外壳命令编译它们。 移动创建类的UI,UI现在将recogonize新类和可以显示其属性。

这可能不会产生任何的内存占用和高内存利用率/泄漏。 此外,我们正在更换这些简单的DLL文件。 唯一的问题是该类一代。 它必须以一种团队必须能够在这个UI执行任何操作sophasticated。 你们有什么感想

Answer 1:

尝试用MSIL工作

public class RunTimeObject<T> where T : class
{

    void EmitGetter(MethodBuilder methodBuilder, FieldBuilder fieldBuilder)
    {
        ILGenerator ilGenerator = methodBuilder.GetILGenerator();
        ilGenerator.Emit(OpCodes.Ldarg_0);
        ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder);
        ilGenerator.Emit(OpCodes.Ret);
    }

    void EmitSetter(MethodBuilder methodBuilder, FieldBuilder fieldBuilder)
    {
        ILGenerator ilGenerator = methodBuilder.GetILGenerator();
        ilGenerator.Emit(OpCodes.Ldarg_0);
        ilGenerator.Emit(OpCodes.Ldarg_1);
        ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
        ilGenerator.Emit(OpCodes.Ret);
    }

    public object CreateNewObject(T obj)
    {

        AssemblyName assemblyName = new AssemblyName { Name = "assembly" };
        AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("module");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicType", TypeAttributes.Public | TypeAttributes.Class);

        foreach (var prop in obj.GetType().GetProperties())
        {
            FieldBuilder field = typeBuilder.DefineField("_" + prop.Name, typeof(string), FieldAttributes.Private);

            PropertyBuilder propertyBuilder =
                typeBuilder.DefineProperty(prop.Name,
                                 PropertyAttributes.None,
                                 typeof(string),
                                 new Type[] { typeof(string) });

            MethodAttributes methodAttributes =
                MethodAttributes.Public |
                MethodAttributes.HideBySig;

            MethodBuilder methodBuilderGetter =
                typeBuilder.DefineMethod("get_value",
                                           methodAttributes,
                                           typeof(string),
                                           Type.EmptyTypes);

            EmitGetter(methodBuilderGetter, field);


            MethodBuilder methodBuilderSetter =
                typeBuilder.DefineMethod("set_value",
                                           methodAttributes,
                                           null,
                                           new Type[] { typeof(string) });

            EmitSetter(methodBuilderSetter, field);


            propertyBuilder.SetGetMethod(methodBuilderGetter);
            propertyBuilder.SetSetMethod(methodBuilderSetter);
        }

        Type dynamicType = typeBuilder.CreateType();

        var dynamicObject = Activator.CreateInstance(dynamicType);

        var properties = dynamicType.GetProperties();

        int count = 0;

        foreach (var item in obj.GetType().GetProperties())
            properties[count++].SetValue(dynamicObject, item.GetValue(obj, null), null);

        return dynamicObject;

    }
}


Answer 2:

如果你让他们从你的基类应该做的伎俩继承新的地址和雇员类。

public class Employee
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string AddressCollection { get; set; }
}

public class EmployeeCollection<T> : List<T> where T : Employee
{
  public bool Add(T Data)
  {
    return this.Add(Data);
  }
}

然后派生的员工会是这个样子

public class EmployeePlus : Employee
{
  public string PassportNo { get; set; }
}

如果你想stronly类型集合为EmployeePlus,你可以简单的定义您的收藏就是这样,如果你需要...

public class EmployeeCollection<T> : List<T> where T : Employee
{
  public bool Add(T Data)
  {
    return this.Add(Data);
  }
}

现在员工的强类型集合和派生的对象,可以使用如下

EmployeeCollection<EmployeePlus> employees = 
  new EmployeeCollection<EmployeePlus>();


Answer 3:

这似乎是一个很奇怪的设置,但有一些,你可以做你想做的方式:

  • 类继承(可能使你的基类抽象,但局部类是另一种选择)
  • 努力接口,而不是类,让您的客户担心实施
  • 扩展方法( ref1用 , ref2用中使用,通常使用的扩展的第三方的代码,但通常不期望的 )。
  • 装饰

通常来讲,我期望与接口在那种情景是工作,但如果你还试图在行为混我大胆地猜测重构,可能是在这一点上和类继承太痛苦是你“会结束了。



文章来源: Help required in adding new methods, properties into existing classes dynamically