ExpandoObject 到静态对象并再次返回。跨越两个领域
我正在寻求与这篇文章进行一些讨论。
我正在考虑将 C# 4.0 动态功能合并到遗留系统中。我的具体示例是在数据层中使用 Rob Connery 的 Massive。但我的问题适用于动态对象必须与现有的强类型业务对象交互的任何地方,以便属性之间存在映射。
我可以使用以下两种(简化的)方法自动实现静态(具体)对象和扩展对象之间的转换:
public static object ToConcrete<T>(System.Dynamic.ExpandoObject dynObject)
{
object instance = Activator.CreateInstance<T>();
var dict = dynObject as IDictionary<string, object>;
PropertyInfo[] targetProperties = instance.GetType().GetProperties();
foreach (PropertyInfo property in targetProperties)
{
object propVal;
if (dict.TryGetValue(property.Name, out propVal))
{
property.SetValue(instance, propVal, null);
}
}
return instance;
}
public static System.Dynamic.ExpandoObject ToExpando(object staticObject)
{
System.Dynamic.ExpandoObject expando = new ExpandoObject();
var dict = expando as IDictionary<string, object>;
PropertyInfo[] properties = staticObject.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
dict[property.Name] = property.GetValue(staticObject, null);
}
return expando;
}
但现在我有很多问题。
我尝试在遗留系统中跨越动态和非动态是否代表了我的误解?意思是,我的工作是否违背了动态的意图?我是否为自己设置了问题?
我对动力学的使用是否应该仅限于完全包含它的组件,而动态对象和静态对象之间没有映射?意思是,尝试混合两种语言域是一种不好的做法吗?我是否创造了糟糕的建筑?反模式?
对于像 Massive 这样的组件,如果我们说在 ExpandoObject 和强类型对象之间映射是不好的做法,那么我无法将其插入到我的遗留系统中,因为它必须将业务对象呈现到遗留代码中,并且在那里我不能或不应该将大型遗留代码库的对象重构为动态对象,这不是一种实用的方法。也许动态无法实际添加到遗留的 .Net 代码库中。也许它必须从一开始就纳入其中,或者根本不纳入。
I'm seeking some discussion with this post.
I'm looking at incorporating C# 4.0 Dynamic features into a legacy system. My explicit example is using Rob Connery's Massive in a data layer. But my questions would apply anywhere a dynamic object must interact with an existing, strongly typed business object such that there is a mapping between properties.
I can automate the conversion to and from static (concrete) objects and expando objects with the following two (simplified) methods:
public static object ToConcrete<T>(System.Dynamic.ExpandoObject dynObject)
{
object instance = Activator.CreateInstance<T>();
var dict = dynObject as IDictionary<string, object>;
PropertyInfo[] targetProperties = instance.GetType().GetProperties();
foreach (PropertyInfo property in targetProperties)
{
object propVal;
if (dict.TryGetValue(property.Name, out propVal))
{
property.SetValue(instance, propVal, null);
}
}
return instance;
}
public static System.Dynamic.ExpandoObject ToExpando(object staticObject)
{
System.Dynamic.ExpandoObject expando = new ExpandoObject();
var dict = expando as IDictionary<string, object>;
PropertyInfo[] properties = staticObject.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
dict[property.Name] = property.GetValue(staticObject, null);
}
return expando;
}
But now I have a number of questions.
Does my attempt to span dynamic and non-dynamic in a legacy system represent a misconception on my part? Meaning, am I working against dynamic's intent? Am I setting myself up for problems?
Should my use of dynamics be limited to components that completely contain it with no mapping between dynamic objects and static objects? Meaning, is it bad practice to attempt to mix the two language domains? Am I creating bad architecture? An anti-pattern?
In the case of a component like Massive, if we say it is bad practice to map between ExpandoObject and strongly typed objects, then there is no way I can plug it into my legacy system since it must surface business objects into the legacy code and there is no practical way I can, or should, refactor the objects of a large, legacy code base into dynamic objects. Maybe dynamic can't be realistically added to a legacy .Net code base. Maybe it has to be incorporated from the beginning, or not at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,您只想将静态类型对象映射到动态对象,以便它们可以在 Massive 中使用。我认为这很好,就像将业务对象映射到 LINQ to SQL 对象,这样您就可以使用该 ORM。但缺点是您最终将映射数据库内外的所有内容。这可能会成为一种痛苦。 LINQ to SQL 对我来说很痛苦。
想想更改代码会是什么样子,然后您就可以衡量这种方法的有效性。对我来说,当我需要向业务对象添加属性时,我必须:
表
这是一件痛苦的事情。如果您的映射助手工作正常,则您使用 Massive 的方法意味着您必须执行以下操作:
表
这还不错。另外,如何处理对象图?如果您有一个人员表和一个具有 1-M 关系的地址表,这意味着一个人可以有多个地址。如何查询并获取人员列表及其地址?您的地图会是什么样子?
另一种方法是查看 NHibernate 或实体框架是否适合您的情况。它们被设计用于处理静态类型的对象。 Massive 看起来像是专为快速轻松的数据访问而设计的。另一个为静态类型对象构建的快速简单的库是 Dapper。它很容易使用。在 Nuget 上查看一下。事实上,根据我对你情况的了解,我会强烈考虑Dapper。
So you just want to map statically-typed objects to dynamic objects so they can be used in Massive. I think this is fine, it's like mapping business objects to LINQ to SQL objects so you can work with that ORM. A downside though is that you will end up mapping everything in and out of your database. This can become a pain. It's a pain for me with LINQ to SQL.
Think about what it will be like to change code, and you an measure how effective this approach is. For me, when I need to add a property to a business object, I have to:
table
This is a pain. Your approach with Massive, if your mapping helpers work correctly, mean you have to do:
table
That's not bad. Also, how will object graphs be handled? If you have a Person table and an Address table with a 1-M relationship meaning a person can have multiple addresses. How can you query and get a list of people with their addresses? What is your mapping going to look like?
Another approach would be to see if NHibernate or Entity Framework would work in your situation. They are designed to work with statically-typed objects. Massive looks like it's designed for quick and easy data access. Another quick and easy library that is build for statically-typed objects is Dapper. It's easy to use. Check it out on Nuget. Actually, from what I understand of your situation, I'd strongly consider Dapper.