c# Reflection change get method of a property - c#

In my C# project I have a dependency on a 3rd party library. Now I want to write an automated acceptance test for my project. However to invoke the test I need an instance of a class from the 3rd party library. Using reflection I managed to set the values as I needed them apart from one.
Here is the relevant class that I am having the issue with:
public class SystemResults
{
// There must be something like this. However I cannot see it as it is private.
private List<Positions> xyz = new List<Positions>();
public IList<Positions> Positions
{
get
{
return xyz;
}
// This property does not have a set method
}
}
Here is what I have tried so far:
private void InitSystemResults(Type trueSysResType, SystemResults sysRes)
{
List<Position> positions = ImporterTools.GetPositions(PositionsCsv);
trueSysResType.GetProperty("Positions").SetValue(sysRes, positions); // ==> Here I get an exception
}
When I invoke the SetValue() method the following exception is thrown.
System.ArgumentException : Property set method not found.
From this information I figured out, that the class must look as I described above.
Now I would like to proceed with this some how. Has anybody an idea how I can achieve that when I access sysRes.Positions my positions are returned by the get method? Or is there a way to change the get method?

You can use BindingFlags.NonPublic,
FieldInfo[] fields = typeof(SystemResults).GetFields(
BindingFlags.NonPublic |
BindingFlags.Instance).ToArray(); // gets xyz and the other private fields
List<int> testResults = new List<int>() { 1,23,4,5,6,7}; // list of integer to set
SystemResults sysres = new SystemResults(); // instance of object
fields[0].SetValue(sysres, testResults); // I know that fields[0] is xyz (you need to find it first),
// sets list of int to object
Hope helps,

{get;} only properties can have a backing field but Positions may be returning something completely different (not a value of a backing field, but maybe a result of a function).
Your code could accept ISystemResults which you can mock and in real code you could have a class SystemResultsFacade which internally calls the 3rd party code.

Related

C# method syntax similar to object initializer

We have an extension method that accepts an action to initialize an object.
Is there some way to improve the syntax of such a call:
public static T NewRow<T>(this IUow uow, Action<T> action();
// this does internally call
public T NewRow<T>(Action<T> initializer) where T : IBo
{
T bo = NewRow<T>();
initializer.Invoke(bo);
return bo;
}
uow.NewRow<ICustomer>(customer => {
customer.Name = "Zzz";
customer.Info = "Abc"
);
I thought maybe I could use something similar to the object initializer syntax?
uow.NewRow<ICustomer>({
Name: "Zzz",
Info: "Abc"
});
The idea is to get rid of customer.* = ... in every line.
I would be happy for any tip.
INFO:
We are using the latest C# language version
The solution should support IntelliSense (e.g., Name and Info should be proposed to the user)
Edit:
I can't use a constructor because I only have an interface. No class/implementation. The framework behind creates the object to the given interface T bo = NewRow<T>();. Which actual object gets created is decided by the framework
Also initializers like { Name: myOtherVariable.FirstName } should be possible
an Action could be everything, not just a simple assignment. So if a client chosed to make a function-call instead, there literally is nothing to shortcut here. See this for example:
uow.NewRow<IWhatever>(() => Console.WriteLine("tataaaa"););
So no, what you want isn't possible.
However you could create some kind of EventsArgs that hold your names and use those within your NewRow-method. There's no need for an action if all those callbacks should actually be just assignement-calls alltogether.
uow.NewRow<ICustomer>(new MyArgs {
Name = "Zzz",
Info = "Abc"
});
And within NewRow:
public T NewRow<T>(MyArgs args) where T : IBo
{
customer.Name = args.Name;
customer.Info = args.Info;
}

Object oriented programming in c# object definition

I have an object which I have defined , the class which I define my object from that has a variable. The type of this variable is the same as this class, see below:
public class _car
{
public _car()
{
}
_car BMW = null;
}
.
.
.
Pay attention the last line is global definition of an object machine.
My question is if in a method which is not located in _car class does something like this:
public another_Class
{
public another_class()
{
}
public _car machine = new _car();
public int this_Methode()
{
if (Machine.BMW == null){
Machine.BMW = new _car();
return 1;
}
return 0;
}
public void main_Methode()
{
int i=this_Methode();
i+=this_Methode();
//We run main_method in somewhere in our program now you say i is 0 or 1 or2 ?
}
}
think in this way //We run main_method now you tell me i's value? is 0 or 1 or 2?
To respond after your edits:
It's not clear where Machine.BMW is coming from. But if it is available at runtime, then it will be populated by the following method. So the first time it runs, it will return 1 to I.
public int this_Methode()
{
if (Machine.BMW == null){
Machine.BMW = new _car();
return 1;
}
return 0;
}
int i=this_Methode(); //i = 1 as new car was created.
i+=this_Methode(); Unless there is some other code running, this_Methode() will return zero as the car was already created.
you tell me i's value? Is 0 or 1 or 2? It will be 1 based on what you have shown in the code. But if there was other cod that affected Machine.BMW and set it to null, then it would be 2.
I like to create a test project in Visual Studio to try these kinds of things out. There is a free version called Visual Studio Express that you can use. Just create a Console app and try it out. This will help answer these questions quickly as you can try it and see if it works as expected. I do this all the time when something isn't working the way I think it should.
Greg
It looks like you are trying to learn more about C# and classes. Let me give you a few things that may help you out. This is not a direct answer to your question, as more info is needed to properly answer it. But a few pointers in general may help you out and let you clarify the issue:
In your class, the property _car is not initialized with an instance of a BMW, so it will be null when new instances are created.
You then have the line public _car machine = new _car()
This line is most likely inside of a class, as you can't have it just in a C# file on it's own. If this came from a Console.App, it's probably inside the Main Program so it run when you start it, and then it would be available to the rest of the app at runtime.
In another_class, you have a method which check to see if if BMW is null, and if not, it creates a new car. BMW will always be null here, as it has not been created before.
So even though you have the "global" variable, the "another_class" has no direct reference to it, so it's not going to see it. So I think the answer to your question is that it is going to always be null, not "live."

Library to generate class that has inline constructor in another assembly with random data?

I'm receiving event notifications from web services that trigger event handlers with data regarding what triggered the event. I'm trying to test that once an event handler is called that a, b and c are all called with the proper values. This isn't possible without relying on the web service
My solution is to create converters that convert the EventArgs that are returned to my via the services library (Exchange Web Services) to something my dumb objects can understand without relying on third part services. My issue is that the EventArgs class given to my by the EWS library has an internal constructor so there's no easy way to generate an instance of it with random property values without much work with reflection.
For example, I have a simply interface:
public interface IConverter<TFrom, TTo>
{
TTo Convert(TFrom from);
}
and a simple implementation:
public class NotificationEventArgsConverter : IConverter<NotificationEventArgs, NewNotification>
{
public NewNotification Convert(NotificationEventArgs from)
{
return new NewNotification
{
ItemIds = from.Events.Cast<ItemEvent>().Select(x => x.ItemId.ToString())
};
}
}
Question is how can I generate an instance of NotificationEventArgs with random values. Is there a library for this that I missed in my searches?
The entire goal of this is to emulate if I receive an instance of NotificationEventArgs with the following values then NewNotification should resemble x.
Edit
In the meantime I will simply use typeof(T).GetConstructor().
You might want to take a look at AutoFixture:
AutoFixture makes it easier for developers to do Test-Driven Development by automating non-relevant Test Fixture Setup, allowing the Test Developer to focus on the essentials of each test case.
After doing some decompilation of Microsoft.Exchange.WebServices and playing bit with reflection, you can do it for example like this:
var fixture = new Fixture();
// retrieve internal FolderEvent(EventType, DateTime) ctor
// using FolderEvent class as NotificationEvent is abstract
var notificationEventCtor = typeof(FolderEvent).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new Type[] { typeof(EventType), typeof(DateTime) },
null
);
// generate 10 random events with some help of LINQ and AutoFixture
var trashData = Enumerable
.Range(1, 10)
.Select(i => new object[]
{
fixture.CreateAnonymous<EventType>(),
fixture.CreateAnonymous<DateTime>()
})
.Select(p => notificationEventCtor.Invoke(p))
.Cast<NotificationEvent>()
.ToList();
Code above will generate 10 FolderEvents in a list, ready to pass to NotificationEventArgs constructor (which is internal again, so same code applies):
var notificationEventArgsCtor = typeof(NotificationEventArgs).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new Type[]
{
typeof(StreamingSubscription),
typeof(IEnumerable<NotificationEvent>)
},
null
);
var instance = notificationEventArgsCtor
.Invoke(new object[] { null, trashData });
Take a look at the PrivateObject class (specifically these constructor overloads). It wraps all the reflection work for you and allows you to create objects with non-public constructors, as well as access non-public methods and properties of those objects. You can get the underlying objects via the Target property.

Implementing a CVAR system

I would like to implement what I know as a CVAR System, I'm not entirely sure on what the official name of it is (if any).
It's essentially a system used in some programs and video games, where a user can pull down a console and input a command, such as "variable 500" to set that variable to 500. Instances of this can be found in any Half-Life game, Doom and Quake games, and many more. The general idea seems to be to hide the underlying architecture, but still allow protected access, for instance, one may be able to view the value for, say, gravity, but not change it. Some of these values may also be functions, for instance, a user may be able to input "create " to create an enemy type at their location, or some other location specified.
Looking through the Half Life 2 SDK, and from what I remember on the GoldSrc SDK, it seems like they at least implemented "flagging" of sorts, where certain commands would only work under certain conditions, such as if another value was set, or if the user has some permission level.
My initial thought was to create a Dictionary, or an object similar to do that, and use that to bind string values to function delegates, as well as keep a "protection" level of sorts, to limit usage of certain commands. However, this seems rather cumbersome, as I believe I would have to go through and add in a new entry manually for each value or function I wanted to implement. I also don't know if this would give me the control level I'm looking for.
I believe ideally what I would like would be a CVAR System class, as well as a Register function that can take it say, a variable/function delegate, a string to access it, and whatever protection level I need. This way I can add what I need as I see them, so everything is still in it's related classes and files.
I'm really just looking for some ideas here, so my questions are:
Has anyone ever done something like this before, and if so, how?
Would my implementation work? (Theoretically, if not, can you think of a better way?)
If someone is more knowledgeable with how one of the previously mentioned titles does it, can you elaborate on that a bit? It seems to be hard to find documentation on them.
I'm not really looking for specific code, just more of structuring design. And it doesn't have to be "commercial" or work just like another, I just need something to get me going.
Were you thinking about something like this?
class CVAR
{
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float gravity = 0.1f;
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float friction = 0.1f;
[ProtectionLevel(CVARFlags.ReadOnly)]
private string serverVersion = "x.x.x";
public void SetCVARValue(string commandLine) {
string cvarName = GetCvarName(commandLine); // parse the cmd line and get the cvar name from there
object cvarValue = GetCvarValue(commandLine); // parse the value from the string
FieldInfo field = typeof(CVAR).GetField(cvarName);
object[] attributes = field.GetCustomAttributes(typeof(ProtectionLevel), false);
if(attributes.Length > 0) {
ProtectionLevelAttribute attr = (ProtectionLevelAttribute)attributes[0];
if(attr.CheckConditions(World.Instance)) {
field.SetValue(this, cvarValue);
} else {
// error report
}
}
}
}
You could write a parser that looks for commands like
/object_property value
/object_method arg1 arg2
A dictionary, like you suggested, could map those strings to properties and functions. The creation of the dictionary could be done dynamically using reflection by looping through eligible objects, taking their public methods and accessors, and generating a string for them.
Then the dictionary could be mapped in a class for convenience and error checking.
For the methods, the dictionary values could be delegates that take 0..n arguments, for the properties/fields, you will need to be able to some data binding between your actual fields and the dictionary value. UNLESS, your objects themselves refer to the dictionaries for their values, in which case the values only live in place.
To do so, you could simply register your properties using reflection in the object constructor, then call the dictionary in your properties.
[Flags]
public enum CVarAccessibilities
{
Settable,
Gettable
}
public class CVar<T>
{
public CVarAccessibilities Accessibility { get; set; }
T val;
public T Value {
get { return val; }
set
{
if (!Accessibility.HasFlag(CVarAccessibilities.Settable))
return; // just don't set it, maybe print some warning
val = value;
}
}
}
public static class CVarRegistry
{
static Dictionary<string, Object> CVars;
static CVarRegistry { /* use reflections to initialize the dictionary */ }
public static T GetValue<T>(Type owner, string paramName)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
return (T)cvar.Value;
}
public static void SetValue<T>(Type owner, string paramName, T value)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
cvar.Value = value;
}
}
public class MyObject
{
public static int MyRegisteredValue
{
get { return Global.CVarRegistry.GetValue<int>(typeof(MyObject), "MyRegisteredValue"); }
set { Global.CVarRegistry.SetValue(typeof(MyObject), "MyRegisteredValue"); }
}
}
Hope that helps!
This is more commonly known as 'tweak' variables.
Good discussion here: https://gamedev.stackexchange.com/questions/3631/tweaking-and-settings-runtime-variable-modification-and-persistence

Moling DataContext with MS Moles?

How can I mole the DataContext that I'm using in a class to write messages to a table. I'd like to assert that the table LINQ is writing to has the expected count of messages. Here's what i have so far.
var context = new MJustTestingDataContext();
MyMessagewriter writer = new MyMessageWriter(context);
var messageList = new List<MIncmoingMessage>();
MTable<MIncomingMessage> messageTable = new MTable<MIncomingMessage>();
messageTable.Bind(messagesLinqList.AsQueryable());
If I use this code with xUnit in my class under test I'll get this exception
Microsoft.Moles.Framework.Moles.MoleNotImplementedException: DataContext.Dispose() was not moled.
What am I missing here and how to implement DataContext.Dispose() on the mole? I'm using moles standalone without Pex.
When you create a new Mole the default behavior for its methods and properties is to throw a MoleNotImplementedException whenever they are called.
To implement the mole you can do context.Dispose = () => {}; which means that nothing happens when the Dispose method gets called on the moled instance.
I reread the question and you probably are having a problem since Dispose is defined in a base class. To mole base method you need to do the following:
var context = new MJustTestingDataContext();
var baseContext = new MDataContext(context);
baseContext.Dispose = () => {};
You'll need to implement every property/method that gets called by the code under test or you can set the default behavior for the mole instance globally using the method BehaveAsDefaultValue. This way every method in the mole will do nothing and return the default value for it's return type if one exists instead of throwing a MoleNotImplementedException. However if you require this behavior it's better to use a stub than a mole.
I'm having trouble understanding what your test is doing. I had to do something similar yesterday, so I'll share my experience. First, it's important to understand that you don't need to use all the MoleTypes to test your code -- you just need to use Moles to redirect certain parts of your code to lambda expressions. Given a method that does this:
get a list of users to modify from the database
modify every user in the set
send the new set back to the database
I'd like to redirect 1 and 3 to not use the database. For instance, I can redirect the call to SubmitChanges (3) via this code:
bool hitSubmitChanges = false;
int changeCount = 0;
IList<object> updates = null;
// more code here...
// redirect DataContext.SubmitChanges() to a lambda to catch updates
MDataContext.AllInstances.SubmitChanges = (c) =>
{
changeCount = c.GetChangeSet().Updates.Count;
updates = c.GetChangeSet().Updates;
hitSubmitChanges = true;
};
That (and the call to get the users) would be the only Moletypes I'd use in the test. The rest of it would be normal. Then I can use assertions to check the values of changeCount, updates and hitSubmitChanges.

Categories