C# 创建运行时程序集的实例并指定其属性
我需要创建一个通用解决方案,创建从xsd生成的类的实例。例如:C# 创建运行时程序集的实例并指定其属性,c#,system.reflection,C#,System.reflection,我需要创建一个通用解决方案,创建从xsd生成的类的实例。例如: <?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="PS"> <xs:com
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="PS">
<xs:complexType>
<xs:sequence>
<xs:element name="P" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="FXs" maxOccurs="1" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="FX" minOccurs="1">
<xs:complexType>
<xs:attribute name="asOfDate" type="xs:date" use="required" />
<xs:attribute name="currency" type="xs:string" use="required" />
<xs:attribute name="rate" type="xs:decimal" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="PName" type="xs:string" />
<xs:attribute name="currency" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
现在我想要一个通用的解决方案,它可以接受任何xsd(不仅仅是上面提到的)并生成一个程序集。我已经生成了汇编,但现在我的问题是,如何为不知道其中存在哪些属性的类动态分配属性?我的意思是,在创建泛型解决方案时,如何知道一个类正在使用另一个类的对象列表。因此,有一种方法可以获取实例和属性,而不是硬编码类名和属性名称。正如您从上面的代码片段中看到的,我正在将数据集中的值分配给属性。计划是将这些值作为columnname、attributename和parentnode存储在数据库中。
所以P节点中的PName属性将来自列名PName。我希望这样的设计,将不会有任何硬编码在我的代码。你能给我推荐一些例子或设计理念吗
对不起,请原谅我,如果我讲不通,请告诉我。只解析XML而不创建程序集不是更容易吗?您可以使用XmlSchema及其子对象来提取数据库中所需的所有信息。您可以使用处理XML文档的通用框架来操作XML输出。或者,如果确实需要程序集,可以先更改XML,然后将其反序列化为对象
但是,如果您的客户机代码在编译时不应该知道程序集的CLR类型,那么我认为创建程序集首先没有多大意义,您最好创建一种通用的中间数据格式,可以根据需要转换为XML或数据库列。长问题需要一个长答案: I.首先,一个小证明:我已经在处理类/程序集生成有一段时间了。事实上,您可以使用(首选方法)或。但你可能不应该
- 反对这一点的第一个论点是,您的XML模型实际上没有那么有用。好的,您有一个XML,您想将其转换为一个类。为此,您将以某种方式将XML转换为代码(C#或VB甚至IL),然后在运行时编译它以创建动态类。那么,为什么不直接使用代码而不是XML呢李>
- 上面这一点有一个推论:如果在设计时指定类,为什么不编译该类(因此,在编译时生成它)李>
II.这里的设计驱动程序是没有硬代码的
- 首先是哲学分析:你不想硬编码,这是一个悖论李>
- 将源代码中的硬编码字符串最小化是一种很好的做法,主要是因为(1)这些字符串预期会发生变化(2)这可能会使测试更容易。我们可以从这个定义中提取两件事:
- 您应该避免硬代码字符串,而不是程序结构
- 您应该只对那些在编译时预期会更改(“动态”)或未知的内容进行配置。数据库结构绝非如此李>
case "PS":
if (p== null)
p= myAssembly.CreateInstance(cls.FullName);
break;
case "PSP":
myClass = myAssembly.CreateInstance(cls.FullName);
myClass.GetType().GetProperty("PName").SetValue(myClass, dt.Rows[0]["PortfolioName"].ToString(), null);
myClass.GetType().GetProperty("currency").SetValue(myClass, dt.Rows[0]["Currency"].ToString(), null);
if (myClasses == null)
myClasses = Array.CreateInstance(myClass.GetType(), deals.Count());
myClasses.SetValue(myClass, l);
l++;
portfolio.GetType().GetProperty("P").SetValue(p, myClasses, null);