.NET 4.5 CustomReflectionContext:什么是它有用吗? [英] .NET 4.5 CustomReflectionContext: what is it useful for?

查看:134
本文介绍了.NET 4.5 CustomReflectionContext:什么是它有用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么新在.NET Framework 4.5开发preVIEW 提到

能够定制反射上下文来替代默认   通过<反射行为href="http://msdn.microsoft.com/en-us/library/system.reflection.context.customreflectioncontext%28v=vs.110%29.aspx">CustomReflectionContext类。

Ability to customize a reflection context to override default reflection behavior through the CustomReflectionContext class.

什么的目的是 ReflectionContext ? MSDN是不是在这个问题不太清楚。

What is the purpose of the ReflectionContext? MSDN is not quite clear on the subject.

推荐答案

在过去与.NET,一直希望能够通过反射来自动执行某些功能,并能够自定义它们之间的紧张关系。例如,以属性面板在Visual Studio中 - 在场景中这显示了一些.NET类型(例如,在设计图面上的控制),它可以自动发现并显示类型定义了每个公共财产

In the past with .NET, there has been tension between wanting to be able to automate certain features through reflection, and being able to customize them. For example, take the Properties panel in Visual Studio - in scenarios where this shows some .NET type (e.g., a control on a design surface), it can automatically discover and display every public property that the type defines.

因为这意味着每个属性会显示出来,而不控制需要做任何事情的开发利用反射的这种类型的驱动的行为是非常有用的。但是,presents一个问题:如果你想定制的东西是什么,例如:定义分类或自定义编辑UI的特定属性?

Using reflection for this sort of type-driven behaviour is useful because it means that every property will show up without the developer of the control needing to do anything. But it presents a problem: what if you want to customize things, e.g. defining categorization or a custom editing UI for a particular property?

传统的解决方案在.NET是拍了一堆自定义属性到相关的成员。然而,一个问题是,它可能意味着你code表示做一个有意义的工作在运行时的部分最终取决于类仅做任何事情,在设计时 - 依托属性prevents从分离出运行时和设计时间方面。你真的要出货code为自定义UI设计师为VS的属性面板的控制库,最终将在最终用户的机器的一部分?

The classic solution in .NET is to slap a bunch of custom attributes onto the relevant members. However, one problem with that is that it can mean the parts of your code that do a meaningful job at runtime end up depending on classes that only do anything at design time - relying on attributes prevents you from separating out the runtime and design time aspects. Do you really want to ship the code for a custom designer UI for VS's properties panel as part of a control library that will end up on end user machines?

另一个问题是,在某些情况下,你可能要决定什么样动态属性你present。其中的这个最古老的例子(其历史可以追溯到.NET 1.0)是把一个数据集在某种网格控制(无论是客户端或Web)的。有了一个强类型数据集,反射可能是一个合适的方式为格发现哪些属性源提供,但数据集还可以动态地使用,所以你需要一种方法在数据网格要求在运行时显示的内容列。

Another problem is that in some situations you may want to decide dynamically what 'properties' you present. One of the oldest examples of this (dating back to .NET 1.0) was putting a DataSet in some sort of grid control (either client-side or web). With a strongly-typed dataset, reflection might be an appropriate way for the grid to discover which properties the source provides, but DataSet could also be used dynamically, so you need a way for the data grid to ask at runtime what columns to display.

(一的回答是:设计你的UI可以正确地生成网格直接这样会导致可怕的用户体验然而,很多人想这样做,偷懒的方法,它是否是一个好主意或不...! )

(One answer to this is: design your UI properly! Generating grids directly like this leads to horrible user experiences. However, a lot of people want to do it the lazy way, whether it's a good idea or not...)

所以,你再遇到这样的情况,有时你要反思驱动的行为,但有时你希望能够采取总量控制在运行时。

So you then have a situation where sometimes you want reflection-driven behaviour, but sometimes you want to be able to take total control at runtime.

各种临时的解决方案出现了这一点。你有整个 TypeDescriptor 的PropertyDescriptor 家庭类型,提供了一种在反思之上虚拟化的看法。默认情况下,这将只是直接通过从反射传递的一切,但类型有机会选择到提供定制的描述符在运行时,使他们能够修改甚至完全取代他们如何看。 ICustomTypeDescriptor 是世界的一部分。

Various ad hoc solutions emerged for this. You have the whole TypeDescriptor and PropertyDescriptor family of types, which provide a sort of virtualizable view on top of reflection. By default, this would just pass everything straight through from reflection but types have the opportunity to opt into providing custom descriptors at runtime, enabling them to modify or even completely replace how they look. ICustomTypeDescriptor is part of that world.

这提供了一个解决方案,以希望反射驱动的行为默认的选项,如果你想让它提供运行驱动行为的问题。但它并没有解决,你只需要在设计时要做到这一点的问题,你不希望有出货的code作为运行时可再发行的部分。

That provides one solution to the issue of wanting reflection-driven behaviour by default with the option to provide runtime-driven behaviour if you want it. But it doesn't solve the problem where you only want to do this at design time, and you don't want to have to ship that code as part of your runtime redistributables.

因此​​在几年前,Visual Studio的推出了自己的临时机制,在设计时充实类型信息。有一堆约定驱动的行为中,Visual Studio会自动发现与特定的运行时组件的设计时组件,使您无需烘烤相关code到您再分发定制的设计经验。共混物也使用此机制,尽管有一些调整,使得有可能提供不同的设计者片断为VS和混合

So a few years ago, Visual Studio introduced its own ad hoc mechanisms for augmenting type information at design time. There's a bunch of convention-driven behaviour in which Visual Studio will automatically discover the design-time components that related to particular runtime components, enabling you to customize the design experience without needing to bake the relevant code into your redistributables. Blend also uses this mechanism, although with some tweaks, making it possible to provide different designer pieces for VS and Blend.

当然,没有这可见通过正常的反射API - VS和Blend都有一层包装,坐在反思之上,以使这一切工作

Of course, none of that's visible through the normal reflection APIs - VS and Blend have a wrapper layer that sits on top of reflection to make this all work.

因此​​,可以通过传递到反射,或者可以增加什么出来的反思,现在我们有两个虚拟化层...

So now we've got two virtualization layers that can pass through to reflection, or can augment what comes out of reflection...

它看起来像在.NET 4.5中,CLR团队决定,由于各种团体已经在做这样的事情,和其他团体想要做更多的它(MEF队不得不进行反思驱动 - 与 - 类似的要求可选的运行时,增强的行为),这是东西正是那种应该建成运行。

It looks like in .NET 4.5, the CLR team decided that since various groups were already doing this sort of thing, and other groups wanted to do more of it (the MEF team had similar requirements for reflection-driven-with-optional-runtime-augmentation behaviour), this was exactly the sort of thing that should be built into the runtime.

新的模式似乎是这样的: ReflectionContext 基类是一个抽象的API,通过它可以得到反射API的虚拟化版本。这看似简单,因为主要思路之一是,你不再需要专门的API喜欢的类型描述符系统,如果你唯一的目标是获得一个虚拟化的包装上反射的顶部 - 反思现在虚拟化的开箱即用。所以,你可以写这样的事情

The new model seems to be this: the ReflectionContext base class is an abstract API through which you can get a virtualized version of the reflection API. It's deceptively simple, because one of the main ideas is that you no longer need specialized APIs like the type descriptor system if your only goal is to get a virtualizable wrapper on top of reflection - reflection is now virtualizable out of the box. So you can write this sort of thing

public static void ShowAllAttributes(Type t)
{
    foreach (Attribute attr in t.GetCustomAttributes(true))
    {
        Console.WriteLine(attr);
    }
}

现在,你一直都能够编写,但在此之前的.NET 4.5,code这样会始终对真实的类型信息的工作,因为它使用了反思。但由于反射环境中,它现在可以提供这一点的,虚拟化的键入。所以认为这很无聊类型:

Now you've always been able to write that, but prior to .NET 4.5, code like this would always be working against 'real' type information because it uses Reflection. But thanks to reflection contexts, it's now possible to provide this with a virtualized Type. So consider this very boring type:

class NoRealAttributes
{
}

如果你只是通过的typeof(NoRealAttributes)我的 ShowAllAttributes 的方法,它会打印出什么。但是,我可以写一个(有点做作)的自定义反射上下文:

If you just pass typeof(NoRealAttributes) to my ShowAllAttributes method, it will print out nothing. But I can write a (somewhat contrived) custom reflection context:

class MyReflectionContext : CustomReflectionContext
{
    protected override IEnumerable<object> GetCustomAttributes(MemberInfo member, IEnumerable<object> declaredAttributes)
    {
        if (member == typeof(NoRealAttributes))
        {
            return new[] { new DefaultMemberAttribute("Foo") };
        }
        else
        {
            return base.GetCustomAttributes(member, declaredAttributes);
        }
    }
}

(顺便说一句,我觉得在 CustomReflectionContext 的区别和它的基地, ReflectionContext 是后者定义对于虚拟化的思考背景下的API,而 CustomReflectionContext 增加了一些帮手,使你更容易实现这样的事情。)现在,我可以用它来提供一个虚拟化版本的键入我的类:

(By the way, I think the distinction between CustomReflectionContext and its base, ReflectionContext is that the latter defines the API for a virtualizable reflection context, while CustomReflectionContext adds some helpers to make it easier for you to implement such a thing.) And now I can use that to provide a virtualized version of the Type for my class:

var ctx = new MyReflectionContext();
Type mapped = ctx.MapType(typeof(NoRealAttributes).GetTypeInfo());
ShowAllAttributes(mapped);

在此code,映射还是指键入对象,所以任何一个知道如何使用反射API将能够与它的工作,但现在会报告一个属性,它实际上不是那里的presence。当然,键入是抽象的,所以我们一直有这与派生的东西,如果你调用 mapped.GetType()你会发现它实际上是一个 System.Reflection.Context.Custom.CustomType ,而不是 System.RuntimeType 你通常看到的。这 CustomType 对象属于我的自定义背景,所以任何其他反射API对象,你会得到通过它(保持如,如果你写了 mapped.Assembly .GetTypes()),你会也得到了通过我的自定义背景下,这将有机会改变其他任何东西,出来定制对象。

In this code, mapped still refers to a Type object, so anything that knows how to use the reflection API will be able to work with it, but it will now report the presence of an attribute that isn't actually there. Of course, Type is abstract, so we always have something that's derived from that, and if you call mapped.GetType() you'll see that it's actually a System.Reflection.Context.Custom.CustomType rather than the System.RuntimeType you'd normally see. And that CustomType object belongs to my custom context, so anything other reflection API objects you get hold of through it (e.g., if you wrote mapped.Assembly.GetTypes()) you'd also get customized objects that go through my custom context, which would have the opportunity to modify anything else that comes out.

所以,code可以使用自定义的键入对象通过类型系统导航。尽管这样的code使用的是普通的基本反射API,我现在有机会定制任何东西散发出来的,如果我认为合适的。

So code can navigate through the type system using the customized Type object. Even though such code is using the ordinary basic reflection API, I now have the opportunity to customize anything that comes out of that if I see fit.

您只要你提出要求,得到这个虚拟化的看法。例如,MEF在.NET 4.5查找自定义属性,指定它应该使用一个用户提供定制的反射情况下,反而会回落到普通的反射,否则。 (在我的 ShowAllAttributes 方法的情况下,使用任何键入对象,我选择传中 - 它不'知道它是否得到一个虚拟的或真正的类型的对象。)

You only get this virtualized view if you ask for it. For example, MEF in .NET 4.5 looks for a custom attribute specifying that it should use a user-supplied custom reflection context, but will fall back to ordinary reflection otherwise. (And in the case of my ShowAllAttributes method, it uses whatever Type object I choose to pass in - it doesn't know if it's getting a virtualized or a 'real' type object.)

因此​​,在短期,这意味着如果你想虚拟化类型的信息,你不再需要周围的反射API特设包装。

So in short, this means you no longer need ad hoc wrappers around the reflection API if you want virtualized type information.

这篇关于.NET 4.5 CustomReflectionContext:什么是它有用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆