如何利用 C# 属性和反射在标记对象上注入/强制后期绑定?
我喜欢设计模式,问题是有些设计模式实施起来确实很乏味。 例如,装饰一个具有 20 多个成员的对象实在是太烦人了。
因此,我想创建一个很好的设计模式库,将其应用于类(作为基类或属性),以使这些模式的实现更快、更容易。
问题是......我不太确定从哪里开始 - 因为我大多不熟悉属性和反射。
如果可能的话,我想利用属性来标记单例(类似于导出标签)、多例和装饰器。但我什至不知道从哪里开始来创建一个改变其实例功能的单例属性。
我有限的研究使我相信,通过属性使用反射/后期绑定并获得对程序集中所有标记类的访问权限,将允许您将单例组合在一起......但我仍然不完全确定这会如何完成吧。
我发现一个名为 Ninject 1.0 的框架,创建了一个 Singleton 属性 - 但该库是如此广泛且没有文档记录,以至于我我目前无法遵循其逻辑。
我觉得具有这种功能的库将为许多开发人员做出巨大贡献。因此,如果有人能够提供一些示例代码,让我找到正确的方向来创建这些模式之一作为属性,那么我将不胜感激 - 其代码不会过度涉及。或者如果有人愿意引导我完成 Ninject 的单例属性实现,这样我就可以解决这个问题...
感谢您的时间和考虑。
I love design patterns, the problem is that some can be really tedious to implement.
For example, decorating an object that has 20+ members is just plain annoying.
So, I wanted to create a nice library of design patterns to be applied to classes (either as base classes or attributes) to make implementation of these patterns much quicker and eaiser.
The problem is...I'm not quite sure where to start - because I am mostly unfamiliar with attributes and reflection.
I would like to utilize attributes to mark Singletons (similar to the Export tag), Multitons, and Decorators...if at all possible. But I don't even know where to start in order to create a singleton attribute that alters the functionality of its instances.
My limited research has led me to believe that using reflection/late binding through an attribute and gaining access to all marked classes in the assembly, would allow you to hack together a singleton...but I'm still not entirely sure how that would be done.
A framework I found, called Ninject 1.0, created a Singleton attribute - but the library is so extensive and undocumented, that I am currently unable to follow its logic.
I feel like a library with this sort of functionality would be a great contribution to many developers out there. So, it would be greatly appreciated if someone could provide some sample code that gets me pointed in the right direction to create one of these patterns as an attribute - whose code isn't overly involved. Or if someone would be willing to walk me through Ninject's singleton attribute implementation so I may work off of that...
Thank you for your time and consideration.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您对设计模式的含义有些困惑。
模式实际上是一种常见的做事方式,旨在解决特定问题。
您并不是真的为了模式而使用模式。使用更多模式并不一定意味着好的。您使用模式来解决类型问题 - 并且希望该模式是解决该问题的公认最佳实践方法。不要尝试将模式应用到您的代码中,因为您可以。
现在,经历了这一切之后,确实可以看出您计划做的事情并不是实现模式的正确方法。您不会用属性等标记代码,然后将它们称为模式。该模式是您的代码。您的代码就是模式。例如,除非类真正实现了发布/订阅功能,否则您不会在类上标记发布者/订阅者模式。例如,你不给一个类标记“Singleton”,那么它就变成了单例模式;使用单例模式要求您围绕该设计编写程序(和类)。
但是,您可以使用某些属性来标记代码或类,这些属性可以帮助检查代码/类是否符合特定模式。
例如,您可以实现一个类型检查器来检查所有类,检查是否有任何标记为“publisher”,并查看该类是否实现“IPublisher”接口。或者,您的类型检查器可以检查是否有任何类被标记为“Singleton”,构造函数是否允许在任一时间构造多个实例。
但属性和反射通常不是实现模式的工具。
在没有多重继承的 C# 中,实现模式的方式有时仅通过基类。例如,您可以通过声明“SingletonObject”基类来实现“单例”模式,该基类将自身限制为仅一个实例化。然后,您可以从该基类派生任何您想要成为单例的类。例如,您可以通过声明 IPublisher 和 ISubscriber 接口来实现“发布/订阅”模式。
现在,如果您真的只想在 C# 类上使用装饰器模式(根据您的问题的标题),那么您正在寻找的是自动包装对象生成器。您可以将包装器基于 ExpandoObject,循环访问基础对象的属性,并将属性添加到仅委托回基础对象的 ExpandoObject。然后将新属性添加到基础对象之上的 ExpandoObject。瞧!您将获得自动装饰器模式包装器类生成器。
I think you have a slight confusion on what design patterns mean.
A pattern is really a common way of doing things, designed to solve a particular problem.
You don't really use patterns for patterns' sake. More patterns usage doesn't automatically means good. You use a pattern to solve a type problem -- and hopefully that pattern is the recognized best-practice way to solve that problem. Don't try to appy a pattern to your code because you can.
Now, after all this, it can really be seen that what you are planning to do is not the right way of going about implementing pattern(s). You don't mark code with attributes etc. and then call them patterns. The pattern is your code. Your code is the pattern. For example, you don't mark a publisher/subscriber pattern on a class unless it really implements publish/subscribe functionalities. For example, you don't mark a class with "Singleton" and then it becomes a singleton pattern; using the Singleton pattern requires you to code your program (and your classes) around that design.
You may, however, mark code or classes with certain attributes that can aid in checking whether the code/classes conform to a particular pattern.
For example, you may implement a type checker that goes through all your class, check if anything is marked "publisher" and see if that class implements the "IPublisher" interface. Or your type checker can check if any class is marked "Singleton" whether the constructor allows construction of more than one instance at any one time.
But attributes and reflection is typically not the tools to implement a pattern.
In C#, where there is no multiple inheritance, the way you implement patterns is sometimes through the base class only. For example, you may implement a "singleton" pattern by declaring a "SingletonObject" base class which limits itself to only one instantiation. Then you derive any class that you want to be singletons from this base class. For example, you may implement a "publish/subscribe" pattern by declaring IPublisher and ISubscriber interfaces.
Now, if you really just want to just use the Decorator pattern on C# classes (as per the title of your question), what you are looking for is an automatic wrapper object generator. You can based your wrapper on an ExpandoObject, loop through the properties of the base object, and add properties to the ExpandoObject that simply delegates back to the base object. Then add new properties to the ExpandoObject on top of your base object. Voila! You get your auto-Decorator-Pattern wrapper class generator.