Just a thought, I think the naming conventions of Reflector are somewhat inconsistent. It contains GetNonPublicVariable and GetPrivateVariable among other things. These methods are actually are capable of accessing public fields too. Also the .Net framework refers to fields not variables and to invoking a method not running it.
Much of the design of Reflector seems to be focused on accessing non-public members but I can see that it is also of use accessing the contents of late-bound types such as COM objects that do not have registered wrappers.
How about we update the names of these methods like so:
GetField : Gets a public field SetField : Sets a public field GetProperty : Gets a public property SetProperty : Sets a public property InvokeMethod : Invokes a public method AddEventHandler RemoveEventHandler
GetNonPublicField : Gets a non-public field SetNonPublicField : Sets a non-public field GetNonPublicProperty : Gets a non-public property SetNonPublicProperty : Sets a non-public property InvokeNonPublicMethod : Invokes a non-public method AddNonPublicEventHandler RemoveNonPublicEventHandler
(Also provide static flavours like GetStaticField, SetStaticField, etc...)
I also dislike having to specify the assembly partial name like that. How about a bunch of factory methods?
-----Original Message----- From: MbUnitDev@googlegroups.com [mailto:MbUnitDev@googlegroups.com] On
Behalf Of Vadim Sent: Thursday, April 12, 2007 10:47 AM To: MbUnit.Dev Cc: astopf...@gmail.com Subject: MbUnit Testing Non-Public classes and Non-public constuctors.
I extended Reflector class to test non-public classes and non-public constructors. My question is what the best place to put the modified files?
Here's an example of testing Microsoft internal struct __DTString that is part of mscorlib.dll.
[Test] public void InternalConstructorTest() { DateTimeFormatInfo dtfi = new DateTimeFormatInfo(); Reflector _reflector = new Reflector("mscorlib.dll", "System.__DTString", "MbUnit", dtfi); Assert.AreEqual(true, _reflector.RunPrivateMethod("Match", "MbUnit")); }
Sorry, it took me awhile to reply to your post. I was very busy at work dealing with crisis. I barely had time to read (not to reply) my emails.
> Just a thought, I think the naming conventions of Reflector are somewhat > inconsistent.
I agree some naming conventions are inconsistent. Unfortunately, it's not very easy to change the names because we don't know how many people are using Reflector. What we can do is to decorate old methods with Obsolete attribute and remove them in version 3.0. However, I guess we need other people opinion.
Andrew, Do you have any ideas?
> It contains GetNonPublicVariable and GetPrivateVariable among other > things.
GetNonPublicVariable is a static method where GetPrivateVariable is an instance method. I personally prefer to work with instance methods.
GetNonPublicVariable is decorated with Obsolete attribute (see snippet of code below) and prefer method is GetNonPublicField.
[Obsolete("Use GetNonPublicField instead")] public object GetPrivateVariable(string variableName)
> Much of the design of Reflector seems to be focused on accessing > non-public members but I can see that it is also of use accessing the > contents of late-bound types such as COM objects that do not have > registered wrappers.
Ability to access public members is a free bonus that doesn't cost much to implement; however, I don't see why people will use Reflector to access public members when they can access the directly. Actually, people might use Reflector, to access public members of non-public class or struct. GetNonPublicXXX name was chosen on purpose. I believe that this is a very good discussion. I'd like to here other people opinion.
I have to run now but I'll try to talk more on this subject.
Jeff, thanks again for talking about this.
Vadim
On Apr 18, 10:42 pm, "Jeff Brown" <J...@ingenio.com> wrote:
> Just a thought, I think the naming conventions of Reflector are somewhat > inconsistent. > It contains GetNonPublicVariable and GetPrivateVariable among other > things. These methods are actually are capable of accessing public > fields too. Also the .Net framework refers to fields not variables and > to invoking a method not running it.
> Much of the design of Reflector seems to be focused on accessing > non-public members but I can see that it is also of use accessing the > contents of late-bound types such as COM objects that do not have > registered wrappers.
> How about we update the names of these methods like so:
> GetField : Gets a public field > SetField : Sets a public field > GetProperty : Gets a public property > SetProperty : Sets a public property > InvokeMethod : Invokes a public method > AddEventHandler > RemoveEventHandler
> GetNonPublicField : Gets a non-public field > SetNonPublicField : Sets a non-public field > GetNonPublicProperty : Gets a non-public property > SetNonPublicProperty : Sets a non-public property > InvokeNonPublicMethod : Invokes a non-public method > AddNonPublicEventHandler > RemoveNonPublicEventHandler
> (Also provide static flavours like GetStaticField, SetStaticField, > etc...)
> I also dislike having to specify the assembly partial name like that. > How about a bunch of factory methods?
If we settle for a scheme in Gallio then if anything is obsolete we can indicate it in the migration documentation, making sure we have clean and agreed syntax for Gallio will be important.
> Sorry, it took me awhile to reply to your post. I was very busy at > work dealing with crisis. I barely had time to read (not to reply) my > emails.
> > Just a thought, I think the naming conventions of Reflector are somewhat > > inconsistent.
> I agree some naming conventions are inconsistent. Unfortunately, it's > not very easy to change the names because we don't know how many > people are using Reflector. What we can do is to decorate old methods > with Obsolete attribute and remove them in version 3.0. However, I > guess we need other people opinion.
> Andrew, Do you have any ideas?
> > It contains GetNonPublicVariable and GetPrivateVariable among other > > things.
> GetNonPublicVariable is a static method where GetPrivateVariable is an > instance method. > I personally prefer to work with instance methods.
> GetNonPublicVariable is decorated with Obsolete attribute (see snippet > of code below) and prefer method is GetNonPublicField.
> [Obsolete("Use GetNonPublicField instead")] > public object GetPrivateVariable(string variableName)
> > Much of the design of Reflector seems to be focused on accessing > > non-public members but I can see that it is also of use accessing the > > contents of late-bound types such as COM objects that do not have > > registered wrappers.
> Ability to access public members is a free bonus that doesn't cost > much to implement; however, I don't see why people will use Reflector > to access public members when they can access the directly. Actually, > people might use Reflector, to access public members of non-public > class or struct. GetNonPublicXXX name was chosen on purpose. I > believe that this is a very good discussion. I'd like to here other > people opinion.
> I have to run now but I'll try to talk more on this subject.
> Jeff, thanks again for talking about this.
> Vadim
> On Apr 18, 10:42 pm, "Jeff Brown" <J...@ingenio.com> wrote: > > Just a thought, I think the naming conventions of Reflector are somewhat > > inconsistent. > > It contains GetNonPublicVariable and GetPrivateVariable among other > > things. These methods are actually are capable of accessing public > > fields too. Also the .Net framework refers to fields not variables and > > to invoking a method not running it.
> > Much of the design of Reflector seems to be focused on accessing > > non-public members but I can see that it is also of use accessing the > > contents of late-bound types such as COM objects that do not have > > registered wrappers.
> > How about we update the names of these methods like so:
> > GetField : Gets a public field > > SetField : Sets a public field > > GetProperty : Gets a public property > > SetProperty : Sets a public property > > InvokeMethod : Invokes a public method > > AddEventHandler > > RemoveEventHandler
> > GetNonPublicField : Gets a non-public field > > SetNonPublicField : Sets a non-public field > > GetNonPublicProperty : Gets a non-public property > > SetNonPublicProperty : Sets a non-public property > > InvokeNonPublicMethod : Invokes a non-public method > > AddNonPublicEventHandler > > RemoveNonPublicEventHandler
> > (Also provide static flavours like GetStaticField, SetStaticField, > > etc...)
> > I also dislike having to specify the assembly partial name like that. > > How about a bunch of factory methods?
> > It would also be useful to provide the following getters:
> > Type Type { get; } : Gets the type of the reflected object. > > object Instance { get; } : Gets the contained instance.
> > Finally, method invocation should automatically unwrap Reflector > > instances passed in as parameters before calling the method.
> > Jeff.
> > -----Original Message----- > > From: MbUnitDev@googlegroups.com [mailto:MbUnitDev@googlegroups.com] On
> > Behalf Of Vadim > > Sent: Thursday, April 12, 2007 10:47 AM > > To: MbUnit.Dev > > Cc: astopf...@gmail.com > > Subject: MbUnit Testing Non-Public classes and Non-public constuctors.
> > I extended Reflector class to test non-public classes and non-public > > constructors. My question is what the best place to put the modified > > files?
> > Here's an example of testing Microsoft internal struct __DTString that > > is part of mscorlib.dll.
We can rename Reflector members and create new ones as Jeff suggests. I'm not sure if we need to do different implementation for public, non- public, and static members. I believe that in most cases when people need to access public members on a public class/struct, they will do it directly without using the Reflector class.
What do you think about these names (Jeff suggested them for public members only).
GetField : Gets a public/non-public/static field (Exists: needs to be renamed) SetField : Sets a public/non-public/static field (New: needs to be created) GetProperty : Gets a public/non-public/static property (Exists) SetProperty : Sets a public/non-public/static property (New) InvokeMethod : Invokes a public/non-public/static method (Exists) AddEventHandler (New) RemoveEventHandler (New)
I like suggestion about CreatInstance. The method below is fine. CreateInstanceFromAssembly(string assemblyName, string typeName, params object[] args);
we also can add these methods: CreateInstanceFromAssembly(string assemblyName, string typeName); CreateInstanceFromAssembly(Assembly assembly, string typeName); CreateInstanceFromAssembly(Assembly assembly, string typeName, params object[] args);
However, the methods below need to know from which assembly they need to create instance. CreateInstance(Type type, params object[] args); CreateInstance(string typeName, params object[] args);
We can create an Assembly property. That means that a user needs to set assembly before calling the two methods above. If assembly is not set, we have to throw an exception. Is that what we want?
Here a list of utilities Jeff suggested:
Assembly Reflector.GetAssembly(string assemblyName); Type Reflector.GetType(string type); Type Reflector.GetTypeFromAssembly(string assemblyName, string typeName); Delegate Reflector.CreateDelegate(Type delegateType, object targetObject, MethodInfo targetMethod);
Type Type { get; } : Gets the type of the reflected object. object Instance { get; } : Gets the contained instance.
I'm writing some new Custom Test Attributes (inheriting from DecoratorPatternAttribute) and I was wondering if there's any way to get the test method from within my RunInvoker?
The reason I need this is I want my invoker to extract a resource from the assembly being tested. But at the time that the invoker is being invoked, the test using my custom attribute isn't in the call stack. I figure this would be information that MbUnit would have at the moment, but it doesn't appear to be passing that info to the invoker.
Phil, I would guess that your new attribute includes info about the resource. If so I over came this issue by handling it from my own IRun class in the Reflect method. Notice the call to attribute1.GetData.ParameterCollection. This is getting the resource info. It is stored in the var TestParameter and passed to the test runinvoker's constructor. You could pass anything to the runinvoker in this fashon.
The var names are not all that nice because I figured this out by snagging it from Reflector. I forget why I needed it in VB.NET.
Public Sub Reflect(ByVal tree As RunInvokerTree, ByVal parent AsRunInvokerVertex, ByVal t As Type) Implements IRun.Reflect
Dim TestMethods As ICollection = TypeHelper.GetAttributedMethods(t, GetType(TestWithEachObjectAttribute))
Dim FixtureObjectProviders As Object() = t.GetCustomAttributes(GetType(ObjectProviderFixtureDecoratorAttribute), True)
Dim num1 As Integer
For num1 = 0 To FixtureObjectProviders.Length - 1
Dim attribute1 As ObjectProviderFixtureDecoratorAttribute = CType(FixtureObjectProviders(num1), ObjectProviderFixtureDecoratorAttribute)
Dim TestParameter As Object
For Each TestParameter In attribute1.GetData.ParameterCollection
Dim TestMethodInfo As MethodInfo
For Each TestMethodInfo In TestMethods
Dim attribute2 As TestWithEachObjectAttribute = CType( TypeHelper.GetFirstCustomAttribute(TestMethodInfo, GetType(TestWithEachObjectAttribute)), TestWithEachObjectAttribute)
Dim invoker1 As IRunInvoker = NewTestWithEachObjectRunInvoker( Me, TestMethodInfo, attribute2, TestParameter)
> I'm writing some new Custom Test Attributes (inheriting from > DecoratorPatternAttribute) and I was wondering if there's any way to get the > test method from within my RunInvoker?
> The reason I need this is I want my invoker to extract a resource from the > assembly being tested. But at the time that the invoker is being invoked, > the test using my custom attribute isn't in the call stack. I figure this > would be information that MbUnit would have at the moment, but it doesn't > appear to be passing that info to the invoker.
> Is there something I'm missing?
> Phil
-- Jay Flowers ---------------------------------------------------------------------- http://jayflowers.com ---------------------------------------------------------------------
Thanks Jay? So is that what VB looks like these days? ;)
I noticed the "Reflect" method but wasn't sure what it was used for. Is there any documentation for it? I'm assuming it is called before Execute and gives me the ability to pass information to the Invoker about the code being tested?
Which would extract the specified resource into the destination folder. Could be a useful test attribute to contribute to MbUnit, unless someone already did it. The resource would be embedded in the same assembly as the unit test. I guess I might also need an override that allows you to specify the assembly to extract from.
Phil
From: MbUnitDev@googlegroups.com [mailto:MbUnitDev@googlegroups.com] On Behalf Of Jay Flowers Sent: Friday, April 27, 2007 4:45 AM To: MbUnitDev@googlegroups.com Subject: MbUnit Re: Get Test Method from DecoratorRunInvoker?
Phil, I would guess that your new attribute includes info about the resource. If so I over came this issue by handling it from my own IRun class in the Reflect method. Notice the call to attribute1.GetData.ParameterCollection . This is getting the resource info. It is stored in the var TestParameter and passed to the test runinvoker's constructor. You could pass anything to the runinvoker in this fashon.
The var names are not all that nice because I figured this out by snagging it from Reflector. I forget why I needed it in VB.NET.
Public Sub Reflect(ByVal tree As RunInvokerTree, ByVal parent As RunInvokerVertex, ByVal t As Type) Implements IRun.Reflect
Dim TestMethods As ICollection = TypeHelper.GetAttributedMethods(t, GetType(TestWithEachObjectAttribute))
Dim FixtureObjectProviders As Object() = t.GetCustomAttributes( GetType(ObjectProviderFixtureDecoratorAttribute), True)
Dim num1 As Integer
For num1 = 0 To FixtureObjectProviders.Length - 1
Dim attribute1 As ObjectProviderFixtureDecoratorAttribute = CType(FixtureObjectProviders(num1), ObjectProviderFixtureDecoratorAttribute)
Dim TestParameter As Object
For Each TestParameter In attribute1.GetData.ParameterCollection
Dim TestMethodInfo As MethodInfo
For Each TestMethodInfo In TestMethods
Dim attribute2 As TestWithEachObjectAttribute = CType(TypeHelper.GetFirstCustomAttribute (TestMethodInfo, GetType(TestWithEachObjectAttribute)), TestWithEachObjectAttribute)
Dim invoker1 As IRunInvoker = New TestWithEachObjectRunInvoker( Me, TestMethodInfo, attribute2, TestParameter)
I'm writing some new Custom Test Attributes (inheriting from DecoratorPatternAttribute) and I was wondering if there's any way to get the test method from within my RunInvoker?
The reason I need this is I want my invoker to extract a resource from the assembly being tested. But at the time that the invoker is being invoked, the test using my custom attribute isn't in the call stack. I figure this would be information that MbUnit would have at the moment, but it doesn't appear to be passing that info to the invoker.
Is there something I'm missing?
Phil
-- Jay Flowers ---------------------------------------------------------------------- http://jayflowers.com ---------------------------------------------------------------------
The trick is how to support access to late-bound types easily. Late-binding is usually used because the type or some of its members are inaccessible but that's not the only interesting case. Sometimes the type is loaded dynamically, generated at runtime, or simply does not implement an accessible interface.
Indicating public vs. non-public is useful for documentation purposes. Indicating static usage in some fashion is essential since the calling conventions are different. Does an instance of Reflector exist when accessing static members, or do we just call static functions on Reflector with a suitable Type? Or... how about making a TypeReflector to wrap a Type with extra convenience methods for accessing statics and then make Reflector just wrap intances.
In any case, an assembly is not strictly required for implementing CreateInstance with just a Type or typeName. These can be implemented a bit like this:
// assumes typename is assembly qualified or in the currently executing assembly static Reflector CreateInstance(string typeName, params object[] constructorArgs) { return CreateInstance(Type.GetType(typeName, true), constructorArgs));
return Array.ConvertAll(values, delegate(object value) { Reflector reflectedValue = value as Reflector; return reflectedValue != null ? reflectedValue.Instance : value; });
}
static Reflector Wrap(object value) { Reflector reflectedValue = value as Reflector; return reflectedValue != null ? reflectedValue : new Reflector(reflectedValue);
}
Additional helpers would be useful for situations involving private nested types, creating instances of privately typed delegates, and various other special cases.
-----Original Message----- From: MbUnitDev@googlegroups.com [mailto:MbUnitDev@googlegroups.com] On
Behalf Of Vadim Sent: Thursday, April 26, 2007 4:54 AM To: MbUnit.Dev Subject: MbUnit Re: Reflector suggestions
We can rename Reflector members and create new ones as Jeff suggests. I'm not sure if we need to do different implementation for public, non- public, and static members. I believe that in most cases when people need to access public members on a public class/struct, they will do it directly without using the Reflector class.
What do you think about these names (Jeff suggested them for public members only).
GetField : Gets a public/non-public/static field (Exists: needs to be renamed) SetField : Sets a public/non-public/static field (New: needs to be created) GetProperty : Gets a public/non-public/static property (Exists) SetProperty : Sets a public/non-public/static property (New) InvokeMethod : Invokes a public/non-public/static method (Exists) AddEventHandler (New) RemoveEventHandler (New)
I like suggestion about CreatInstance. The method below is fine. CreateInstanceFromAssembly(string assemblyName, string typeName, params object[] args);
we also can add these methods: CreateInstanceFromAssembly(string assemblyName, string typeName); CreateInstanceFromAssembly(Assembly assembly, string typeName); CreateInstanceFromAssembly(Assembly assembly, string typeName, params object[] args);
However, the methods below need to know from which assembly they need to create instance. CreateInstance(Type type, params object[] args); CreateInstance(string typeName, params object[] args);
We can create an Assembly property. That means that a user needs to set assembly before calling the two methods above. If assembly is not set, we have to throw an exception. Is that what we want?
Here a list of utilities Jeff suggested:
Assembly Reflector.GetAssembly(string assemblyName); Type Reflector.GetType(string type); Type Reflector.GetTypeFromAssembly(string assemblyName, string typeName); Delegate Reflector.CreateDelegate(Type delegateType, object targetObject, MethodInfo targetMethod);
Type Type { get; } : Gets the type of the reflected object. object Instance { get; } : Gets the contained instance.
Andrew, Any idea when you're going to release next build? At my work people want to use MbUnit to test non-public classes. It was checked in about two weeks ago.
Vadim
On Apr 27, 6:14 pm, "Jeff Brown" <J...@ingenio.com> wrote:
> The trick is how to support access to late-bound types easily. > Late-binding is usually used because the type or some of its members are > inaccessible but that's not the only interesting case. Sometimes the > type is loaded dynamically, generated at runtime, or simply does not > implement an accessible interface.
> Indicating public vs. non-public is useful for documentation purposes. > Indicating static usage in some fashion is essential since the calling > conventions are different. Does an instance of Reflector exist when > accessing static members, or do we just call static functions on > Reflector with a suitable Type? Or... how about making a TypeReflector > to wrap a Type with extra convenience methods for accessing statics and > then make Reflector just wrap intances.
> In any case, an assembly is not strictly required for implementing > CreateInstance with just a Type or typeName. These can be implemented a > bit like this:
> static Reflector Wrap(object value) > { > Reflector reflectedValue = value as Reflector; > return reflectedValue != null ? reflectedValue : new > Reflector(reflectedValue);
> }
> Additional helpers would be useful for situations involving private > nested types, creating instances of privately typed delegates, and > various other special cases.
> Jeff.
> -----Original Message----- > From: MbUnitDev@googlegroups.com [mailto:MbUnitDev@googlegroups.com] On
> Behalf Of Vadim > Sent: Thursday, April 26, 2007 4:54 AM > To: MbUnit.Dev > Subject: MbUnit Re: Reflector suggestions
> We can rename Reflector members and create new ones as Jeff suggests. > I'm not sure if we need to do different implementation for public, non- > public, and static members. I believe that in most cases when people > need to access public members on a public class/struct, they will do it > directly without using the Reflector class.
> What do you think about these names (Jeff suggested them for public > members only).
> GetField : Gets a public/non-public/static field (Exists: needs to be > renamed) > SetField : Sets a public/non-public/static field (New: needs to be > created) > GetProperty : Gets a public/non-public/static property (Exists) > SetProperty : Sets a public/non-public/static property (New) > InvokeMethod : Invokes a public/non-public/static method (Exists) > AddEventHandler (New) RemoveEventHandler (New)
> I like suggestion about CreatInstance. The method below is fine. > CreateInstanceFromAssembly(string assemblyName, string typeName, params > object[] args);
> we also can add these methods: > CreateInstanceFromAssembly(string assemblyName, string typeName); > CreateInstanceFromAssembly(Assembly assembly, string typeName); > CreateInstanceFromAssembly(Assembly assembly, string typeName, params > object[] args);
> However, the methods below need to know from which assembly they need to > create instance. > CreateInstance(Type type, params object[] args); CreateInstance(string > typeName, params object[] args);
> We can create an Assembly property. That means that a user needs to set > assembly before calling the two methods above. If assembly is not set, > we have to throw an exception. Is that what we want?
> Andrew, > Any idea when you're going to release next build? At my work people > want to use MbUnit to test non-public classes. It was checked in > about two weeks ago.
> Vadim
> On Apr 27, 6:14 pm, "Jeff Brown" <J...@ingenio.com> wrote: > > The trick is how to support access to late-bound types easily. > > Late-binding is usually used because the type or some of its members are > > inaccessible but that's not the only interesting case. Sometimes the > > type is loaded dynamically, generated at runtime, or simply does not > > implement an accessible interface.
> > Indicating public vs. non-public is useful for documentation purposes. > > Indicating static usage in some fashion is essential since the calling > > conventions are different. Does an instance of Reflector exist when > > accessing static members, or do we just call static functions on > > Reflector with a suitable Type? Or... how about making a TypeReflector > > to wrap a Type with extra convenience methods for accessing statics and > > then make Reflector just wrap intances.
> > In any case, an assembly is not strictly required for implementing > > CreateInstance with just a Type or typeName. These can be implemented a > > bit like this:
> > static Reflector Wrap(object value) > > { > > Reflector reflectedValue = value as Reflector; > > return reflectedValue != null ? reflectedValue : new > > Reflector(reflectedValue);
> > }
> > Additional helpers would be useful for situations involving private > > nested types, creating instances of privately typed delegates, and > > various other special cases.
> > Jeff.
> > -----Original Message----- > > From: MbUnitDev@googlegroups.com [mailto:MbUnitDev@googlegroups.com] On
> > Behalf Of Vadim > > Sent: Thursday, April 26, 2007 4:54 AM > > To: MbUnit.Dev > > Subject: MbUnit Re: Reflector suggestions
> > We can rename Reflector members and create new ones as Jeff suggests. > > I'm not sure if we need to do different implementation for public, non- > > public, and static members. I believe that in most cases when people > > need to access public members on a public class/struct, they will do it > > directly without using the Reflector class.
> > What do you think about these names (Jeff suggested them for public > > members only).
> > GetField : Gets a public/non-public/static field (Exists: needs to be > > renamed) > > SetField : Sets a public/non-public/static field (New: needs to be > > created) > > GetProperty : Gets a public/non-public/static property (Exists) > > SetProperty : Sets a public/non-public/static property (New) > > InvokeMethod : Invokes a public/non-public/static method (Exists) > > AddEventHandler (New) RemoveEventHandler (New)
> > I like suggestion about CreatInstance. The method below is fine. > > CreateInstanceFromAssembly(string assemblyName, string typeName, params > > object[] args);
> > we also can add these methods: > > CreateInstanceFromAssembly(string assemblyName, string typeName); > > CreateInstanceFromAssembly(Assembly assembly, string typeName); > > CreateInstanceFromAssembly(Assembly assembly, string typeName, params > > object[] args);
> > However, the methods below need to know from which assembly they need to > > create instance. > > CreateInstance(Type type, params object[] args); CreateInstance(string > > typeName, params object[] args);
> > We can create an Assembly property. That means that a user needs to set > > assembly before calling the two methods above. If assembly is not set, > > we have to throw an exception. Is that what we want?