how to test if properties is from another assembly - c#

i am trying to test this method:
[Test]
public void Test_GetReferenceValue()
{
Person person= new Person() { Name = "PJ" };
PersonalProperty<Person> personalProperty = new PersonalProperty<Person>();
var result = personalProperty.GetReferenceValue(person);
Assert.AreEqual("PJ", result);
}
the method GetReferenceValue has the following implementation:
public override object GetReferenceValue(TOwner owner)
{
Person value = this.Accessor(owner);
if (value == null)
return null;
else
return value.Name;
}
i tried to find the origin of the Accessor property, and i found it in ANOTHER assembly:
public class PersonalProperty<TOwner> : Property<TOwner, Person>
where TOwner : class
{
public virtual Func<TOwner, TProperty> Accessor { get; internal set; }
}
my test above will run perfectly if only i can put the code in my test:
personalProperty.Accessor = p =>p;
this is to put a definition/method for the Func delegate.. however, i cant do this because Accessor is internally set. Meaning, i cant set it if i am in an another assembly (which i am right now). i cant friend the Accessor's assembly because i am not allowed to change any code. i am only allowed to create a test in an another project/assembly.
so how am i going to test GetReferenceValue? can reflection help?

Yes, you can do it using reflection. This function can set property value ignoring setter access modifier:
public static void SetPropertyValue(object instance, string property, object value)
{
instance.GetType().GetProperty(property).SetValue(instance, value, null);
}
Usage:
Func<Person, Person> accessor = p => p;
SetPropertyValue(personalProperty, "Accessor", accessor);
Anyway, it is an indicator that something might be wrong with PersonalProperty<T> class design.

Related

I want to implement a linq expression that will allow me to test an property on a supplied object

I want to implement this method from MOQ. (Little out of my depth here)
ISetup<T> Setup(Expression<Action<T>> expression);
public class Foo {
public string Bar { get; set; }
public int Baz { get; set; }
}
public class MyCoolClass
{
public ? Evaluate<Expression<Action>>(expression);
//I want to be able to access and test the value of Foo.Bar (see below)
}
public class ClientOfMyClass
{
public void UseTheMethod()
{
MyCoolClass myCool = new MyCoolClass();
bool result = myCool.Evaluate<Foo>(f => f.Bar);
}
}
Basically, I am trying to write a method that will allow the caller to specify a property on an object with an expression, and allow me to test the value of that property and do something with it.
You want to use an Expression<Func<>> parameter, and check that it contains a Body, and a Member of type PropertyInfo, and use GetValue() passing your object in.
public static void Evaluate<TObj,TProp>(
this TObj obj,
Expression<Func<TObj, TProp>> expr)
{
var prop = (expr.Body as MemberExpression)?.Member as PropertyInfo;
var val = prop?.GetValue(obj);
if (val != null) {
//Do something
}
}
Note that the above code requires the passed in lambda to point to a Property. If you want to handle Fields as well as Methods, they will come in as different types of Expressions, and you'll want to handle handle them slightly differently. For more context and usage, here's a Fiddle.
Edit: Updated to work with other property types.

Looking for a more elegant way to perform custom get/set functionality on class properties

I'm trying to find a way to refine some code that I have. I work with a 3rd party API that has a REALLY complicated API request object (I'll call it ScrewyAPIObject) that has tons of repetition in it. Every time you want to set a particular property, it can take a page worth of code. So I built a library to provide a simplified wrapper around the setting/getting of its properties (and to handle some value preprocessing).
Here's a stripped-down view of how it works:
public abstract class LessScrewyWrapper
{
protected ScrewyAPIRequest _screwy = new ScrewyAPIRequest();
public void Set(string value)
{
Set(_getPropertyName(), value);
}
public void Set(string property, string value)
{
// Preprocess value and set the appropriate property on _screwy. This part
// has tons of code, but we'll just say it looks like this:
_screwy.Fields[property] = "[" + value + "]";
}
protected string _getPropertyName()
{
// This method looks at the Environment.StackTrace, finds the correct set_ or
// get_ method call and extracts the property name and returns it.
}
public string Get()
{
// Get the property name being access
string property = _getPropertyName();
// Search _screwy's structure for the value and return it. Again, tons of code,
// so let's just say it looks like this:
return _screwy.Fields[property];
}
public ScrewyAPIRequest GetRequest()
{
return _screwy;
}
}
Then I have a child class that represents one specific type of the screwy API request (there are multiple kinds that all have the same structure but different setups). Let's just say this one has two string properties, PropertyA and PropertyB:
public class SpecificScrewyAPIRequest : LessScrewyWrapper
{
public string PropertyA
{
get { return Get(); }
set { Set(value); }
}
public string PropertyB
{
get { return Get(); }
set { Set(value); }
}
}
Now when I want to go use this library, I can just do:
SpecificScrewyAPIRequest foo = new SpecificScrewyAPIRequest();
foo.PropertyA = "Hello";
foo.PropertyB = "World";
ScrewyAPIRequest request = foo.GetRequest();
This works fine and dandy, but there are different kinds of data types, which involves using generics in my Set/Get methods, and it just makes the child classes look a little kludgy when you're dealing with 50 properties and 50 copies of Get() and Set() calls.
What I'd LIKE to do is simply define fields, like this:
public class SpecificScrewyAPIRequest : LessScrewyWrapper
{
public string PropertyA;
public string PropertyB;
}
It would make the classes look a LOT cleaner. The problem is that I don't know of a way to have .NET make a callback to my custom handlers whenever the values of the fields are accessed and modified.
I've seen someone do something like this in PHP using the __set and __get magic methods (albeit in a way they were not intended to be used), but I haven't found anything similar in C#. Any ideas?
EDIT: I've considered using an indexed approach to my class with an object-type value that is cast to its appropriate type afterwards, but I'd prefer to retain the approach where the property is defined with a specific type.
Maybe in your case DynamicObject is a suitable choice:
public class ScrewyDynamicWrapper : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
// get your actual value based on the property name
Console.WriteLine("Get Property: {0}", binder.Name);
result = null;
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// set your actual value based on the property name
Console.WriteLine("Set Property: {0} # Value: {2}", binder.Name, value);
return true;
}
}
And define your wrapper objects:
public class ScrewyWrapper
{
protected dynamic ActualWrapper = new ScrewyDynamicWrapper();
public int? PropertyA
{
get { return ActualWrapper.PropertyA; }
set { ActualWrapper.PropertyA = value; }
}
public string PropertyB
{
get { return ActualWrapper.PropertyB; }
set { ActualWrapper.PropertyB = value; }
}
}
However, you can't rely on the property type inside ScrewyDynamicWrapper with this approach, so it depends on your actual API requirements - maybe it won't work for you.
Instead of fields, If you define as property in class, It will be more easy.
public class SpecificScrewyAPIRequest
{
public string PropertyA { get; set; }
public string PropertyB { get; set; }
}
Then you can create extension generic method to return ScrewyAPIRequest object.
public static class Extensions
{
public static ScrewyAPIRequest GetRequest<T>(this T obj)
{
ScrewyAPIRequest _screwy = new ScrewyAPIRequest();
var test= obj.GetType().GetProperties();
foreach (var prop in obj.GetType().GetProperties())
{
_screwy.Fields[prop.Name] = prop.GetValue(obj, null);
}
return _screwy;
}
}
Now you can easily get ScrewyAPIRequest from any class object.
Your code will look like following.
SpecificScrewyAPIRequest foo = new SpecificScrewyAPIRequest();
foo.PropertyA = "Hello";
foo.PropertyB = "World";
ScrewyAPIRequest request = foo.GetRequest();

Failing to create type dynamically

I am trying to come up with a method factory that looks inside config to get the full name of the type to instantiate and creates that object type dynamically.
Here is my Type and the Interface:
public interface IComponent<T>
{
IEnumerable<T> DataSource {get; set;}
void PerformTask(object executionContext);
}
namespace MyCompany.Components
{
public class ConcreteComponent1<T> : IComponent<T>
{
private IEnumerable<Contact> contactSource = null;
internal ConcreteComponent1() {}
public void PerformTask(object executionContext)
{
this.contactSource = GetSource(executionContext);
foreach(var result in this.contactSource)
{
result.Execute(executionContext);
}
}
public IEnumerable<T> DataSource
{
get { return this.contactSource as IEnumerable<T>; }
set { this.contactSource = (IContactSource)value; }
}
}
}
Factory, resides in the same assembly:
//Factory - Same assembly
public static class ComponentFactory<T>
{
public static IComponent<T> CreateComponent()
{
var assembly = Assembly.GetExecutingAssembly();
object o = assembly.CreateInstance("MyCompany.Components.ConcreteComponent1"); //o is null...
var objectHandle = Activator.CreateInstance(Assembly.GetAssembl(typeof(ComponentFactory<T>)).GetName().FullName, "MyCompany.Components.ConcreteComponent1"); //throws Could not load type from assembly exception.
return o as IComponent<T>;
}
}
So in first case the o is always null.
In the second case when using the Activator class, it throws Type could not be loaded from assembly "MyAssembly". No inner exception. What am I doing wrong?
First of all, actual name of your type is:
MyCompany.Components.ConcreteComponent1`1
It can't be instantiated because you have to specify type parameters:
public static class ComponentFactory<T>
{
public static IComponent<T> CreateComponent()
{
Type generic = Type.GetType("MyCompany.Components.ConcreteComponent1`1");
Type concrete = generic.MakeGenericType(typeof(T));
var objectHandle = Activator.CreateInstance(
concrete,
BindingFlags.NonPublic | BindingFlags.Instance,
null,
null, //here can come ctor params
null);
return objectHandle as IComponent<T>;
}
}
this will work with internal constructor.
I'd say the actual name of your class ConcreteComponent1 is not "MyCompany.Components.ConcreteComponent1" because it includes a generic. Execute
Console.WriteLine(typeof(ConcreteComponent1<T>).FullName);
to see the string representation for your class created by C#.
But why do you define your ConcreteComponent1 class the way you do? Wouldn't it be better to use something like this:
public class ConcreteComponent1 : IComponent<Contact> {
internal ConcreteComponent1() {}
public void PerformTask(object executionContext)
{
this.contactSource = GetSource(executionContext);
foreach(var result in this.contactSource)
{
result.Execute(executionContext);
}
}
public IEnumerable<Contact> DataSource
{
get { return this.contactSource; }
set { this.contactSource = value; }
}
}
This way you can use the expected name you already used in your example and you can remove the extra private field your approach introduces. As your ConcreteComponent1 class doesn't really need any generic functionality this would be a better approach in my opinion.

c# copy constructor generator

I want to copy values from one object to another object. Something similar to pass by value but with assignment.
For example:
PushPin newValPushPin = oldPushPin; //I want to break the reference here.
I was told to write a copy constructor for this. But this class has a lot of properties, it will probably take an hour to write a copy constructor by hand.
Is there a better way to assign an object to another object by value?
If not, is there a copy constructor generator?
Note: ICloneable is not available in Silverlight.
If you can mark the object that is to be cloned as Serializable then you can use in-memory serialization to create a copy. Check the following code, it has the advantage that it will work on other kinds of objects as well and that you don't have to change your copy constructor or copy code each time an property is added, removed or changed:
class Program
{
static void Main(string[] args)
{
var foo = new Foo(10, "test", new Bar("Detail 1"), new Bar("Detail 2"));
var clonedFoo = foo.Clone();
Console.WriteLine("Id {0} Bar count {1}", clonedFoo.Id, clonedFoo.Bars.Count());
}
}
public static class ClonerExtensions
{
public static TObject Clone<TObject>(this TObject toClone)
{
var formatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
formatter.Serialize(memoryStream, toClone);
memoryStream.Position = 0;
return (TObject) formatter.Deserialize(memoryStream);
}
}
}
[Serializable]
public class Foo
{
public int Id { get; private set; }
public string Name { get; private set; }
public IEnumerable<Bar> Bars { get; private set; }
public Foo(int id, string name, params Bar[] bars)
{
Id = id;
Name = name;
Bars = bars;
}
}
[Serializable]
public class Bar
{
public string Detail { get; private set; }
public Bar(string detail)
{
Detail = detail;
}
}
There is a protected member called "MemberwiseClone", you can write this in your class...
public MyClass Clone(){
return (MyClass)this.MemberwiseClone();
}
then you can access..
MyClass newObject = oldObject.Clone();
The only way (that I'm aware of) to do this, and do it correctly, is to implement the copy yourself. Take for example:
public class FrobAndState
{
public Frob Frobber { get; set;}
public bool State { get; set; }
}
public class Frob
{
public List<int> Values { get; private set; }
public Frob(int[] values)
{
Values = new List<int>(values);
}
}
In this example you'd need to know how Frob was implemented, i.e. the fact that you need to call the constructor to create a copy of it as Values is read-only, to be able to make a copy of a given instance of FrobAndState.
Also - you couldn't just implement FrobAndState.Copy thusly:
public class FrobAndState
{
// ... Properties
public FrobAndState Copy()
{
var new = new FrobAndState();
new.State = this.State;
new.Frobber = this.Frobber;
}
}
Because both the instance of FrobAndState that you called .Copy() on, and the new instance would both have a reference to the same instance of Frobber.
In short, copying things is hard and any Copy implementation is difficult to get right.
C# does not have a copy constructor. There are different ways to tackle this. At the OOP level you could use inheritance or aggregation. AutoMapper might also be worth a try.
I want to copy values from one object
to another object. Something similiar
to pass by value but with assignment.
What do you mean by "with assignment"? If you mean that you want people to be able to say:
a = b;
And for you to define what = means, the only way you can do that in C# is if b is a different type to a and you've defined an implicit conversion (or more tenuously, if a stands for something of the form x.Y where Y is a property with a setter). You can't override = for a simple assignment between identical types in C#.
I was told to write a copy constructor
for this. But this class has alot of
properties, it will probably take an
hour to write a copy constructor by
hand.
If that's really true, then I would guess that you have a different problem. Your class is too big.
If you make your class Serializable you could Serialize it to a MemoryStream and Deserialize to a new instance.
If you want copy-on-assignment you should be using a struct instead of a class. But be careful, it is easy to make subtle mistakes. It is highly recommended that all stucts be immmutable to reduce the chance for error.
Though, this may not answer your question directly, but to add a cent; usually the term Clone is linked with shallow copy(referenced objects). To have a deep copy, I believe you will need to look into the some creational pattern(prototype?). The answer to this question might help.
You implement Justin Angel's method of cloning objects in Silverlight
using System;
using System.Reflection;
using System.Windows;
namespace JustinAngelNet.Silverlight.Framework
{
public static class SilverlightExtensions
{
public static T Clone<T>(T source)
{
T cloned = (T) Activator.CreateInstance(source.GetType());
foreach (PropertyInfo curPropInfo in source.GetType().GetProperties())
{
if (curPropInfo.GetGetMethod() != null
&& (curPropInfo.GetSetMethod() != null))
{
// Handle Non-indexer properties
if (curPropInfo.Name != "Item")
{
// get property from source
object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] {});
// clone if needed
if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject) getValue);
// set property on cloned
if (getValue != null)
curPropInfo.GetSetMethod().Invoke(cloned, new object[] {getValue});
}
// handle indexer
else
{
// get count for indexer
int numberofItemInColleciton =
(int)
curPropInfo.ReflectedType.GetProperty("Count").GetGetMethod().Invoke(source, new object[] {});
// run on indexer
for (int i = 0; i < numberofItemInColleciton; i++)
{
// get item through Indexer
object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] {i});
// clone if needed
if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject) getValue);
// add item to collection
curPropInfo.ReflectedType.GetMethod("Add").Invoke(cloned, new object[] {getValue});
}
}
}
}
return cloned;
}
}
}
Then you can do this
MyClass newObject = SilverlightExtensions.Clone(oldObject);

Is there any way to use an extension method in an object initializer block in C#

The simple demo below captures what I am trying to do. In the real program, I have to use the object initialiser block since it is reading a list in a LINQ to SQL select expression, and there is a value that that I want to read off the database and store on the object, but the object doesn't have a simple property that I can set for that value. Instead it has an XML data store.
It looks like I can't call an extension method in the object initialiser block, and that I can't attach a property using extension methods.
So am I out of luck with this approach? The only alternative seems to be to persuade the owner of the base class to modify it for this scenario.
I have an existing solution where I subclass BaseDataObject, but this has problems too that don't show up in this simple example. The objects are persisted and restored as BaseDataObject - the casts and tests would get complex.
public class BaseDataObject
{
// internal data store
private Dictionary<string, object> attachedData = new Dictionary<string, object>();
public void SetData(string key, object value)
{
attachedData[key] = value;
}
public object GetData(string key)
{
return attachedData[key];
}
public int SomeValue { get; set; }
public int SomeOtherValue { get; set; }
}
public static class Extensions
{
public static void SetBarValue(this BaseDataObject dataObject,
int barValue)
{
/// Cannot attach a property to BaseDataObject?
dataObject.SetData("bar", barValue);
}
}
public class TestDemo
{
public void CreateTest()
{
// this works
BaseDataObject test1 = new BaseDataObject
{ SomeValue = 3, SomeOtherValue = 4 };
// this does not work - it does not compile
// cannot use extension method in the initialiser block
// cannot make an exension property
BaseDataObject test2 = new BaseDataObject { SomeValue = 3, SomeOtherValue = 4, SetBarValue(5) };
}
}
One of the answers (from mattlant) suggests using a fluent interface style extension method. e.g.:
// fluent interface style
public static BaseDataObject SetBarValueWithReturn(this BaseDataObject dataObject, int barValue)
{
dataObject.SetData("bar", barValue);
return dataObject;
}
// this works
BaseDataObject test3 = (new BaseDataObject { SomeValue = 3, SomeOtherValue = 4 }).SetBarValueWithReturn(5);
But will this work in a LINQ query?
Object Initializers are just syntactic sugar that requires a clever compiler, and as of the current implementation you can't call methods in the initializer.
var x = new BaseDataObject { SomeValue = 3, SomeOtherValue = 4 };
Will get compiler to something like this:
BaseDataObject tempObject = new BaseDataObject();
tempObject.SomeValue = 3;
tempObject.SomeOtherValue = 4;
BaseDataObject x = tempObject;
The difference is that there can't be any synchronization issues. The variable x get's assigned the fully assigned BaseDataObject at once, you can't mess with the object during it's initialization.
You could just call the extension method after the object creation:
var x = new BaseDataObject { SomeValue = 3, SomeOtherValue = 4 };
x.SetBarValue()
You could change SetBarValue to be a property with get/set that can be assigned during initialization:
public int BarValue
{
set
{
//Value should be ignored
}
}
Or, you could subclass / use the facade pattern to add the method onto your object:
public class DataObjectWithBarValue : BaseDataObject
{
public void BarValue
{
set
{
SetData("bar", value);
}
get
{
(int) GetData("bar");
}
}
}
No but you could do this....:
BaseDataObject test2 = (new BaseDataObject { SomeValue = 3, SomeOtherValue = 4}).SetBarValue(5);
ANd have your extension return the object like Linq Does.
EDIT: This was a good thought untill i reread and saw that the base class was developed by a third person: aka you dont have the code. Others here have posted a correct solution.
Even better:
public static T SetBarValue<T>(this T dataObject, int barValue)
where T : BaseDataObject
{
dataObject.SetData("bar", barValue);
return dataObject;
}
and you can use this extension method for derived types of BaseDataObject to chain methods without casts and preserve the real type when inferred into a var field or anonymous type.
static T WithBarValue<T>(this T dataObject, int barValue)
where T : BaseDataObject
{ dataObject.SetData("bar", barValue);
return dataObject;
}
var x = new BaseDataObject{SomeValue=3, OtherValue=4}.WithBarValue(5);
Is extending the class a possibility? Then you could easily add the property you need.
Failing that, you can create a new class that has similar properties that simply call back to a private instance of the class you are interested in.
Right, having learned from the answerers, the short answer to "Is there any way to use an extension method in an object initializer block in C#?" is "No."
The way that I eventually solved the problem that I faced (similar, but more complex that the toy problem that I posed here) was a hybrid approach, as follows:
I created a subclass, e.g.
public class SubClassedDataObject : BaseDataObject
{
public int Bar
{
get { return (int)GetData("bar"); }
set { SetData("bar", value); }
}
}
Which works fine in LINQ, the initialisation block looking like
SubClassedDataObject testSub = new SubClassedDataObject
{ SomeValue = 3, SomeOtherValue = 4, Bar = 5 };
But the reason that I didn't like this approach in the first place is that these objects are put into XML and come back out as BaseDataObject, and casting back was going to be an annoyance, an unnecessary data copy, and would put two copies of the same object in play.
In the rest of the code, I ignored the subclasses and used extension methods:
public static void SetBar(this BaseDataObject dataObject, int barValue)
{
dataObject.SetData("bar", barValue);
}
public static int GetBar(this BaseDataObject dataObject)
{
return (int)dataObject.GetData("bar");
}
And it works nicely.

Categories

Resources