Importing a class with a specific parameter - wpf

I got a ViewModel which I export with MEF. I'd like this ViewModel to be initialized differently each time it's being imported, according to an enum/specific object parameter that will be provided to it.
I've been reading a little on the subject and I found that maybe this -
http://msdn.microsoft.com/en-us/library/ee155691.aspx#metadata_and_metadata_views
would be able to fit my needs, but I'm not sure that this would be the best way to do it.
Another method I've been thinking about is importing the class normally, and then once I've an instance, to call a special initialization method that would receive my parameter. However this doesn't seem like a classic MEF implementation, and maybe losses some of its "magic".
I'm hoping someone would be able to point out for me what would be the recommended method to achieve this.
Thanks!

A workaround is exporting a factory that creates instances of your type. While this means you cannot directly import thos instances, it does have the benefit that the logic to create them is the responsability of the factory so users of the class do not have to know about it:
public class ServiceWithParameter
{
public ServiceWithParameter( int a )
{
this.a = a;
}
private readonly int a;
}
[Export]
public class ServiceWithParameterFactory
{
public ServiceWithParameterFactory()
{
instance = 0;
}
public ServiceWithParameter Instance()
{
return new ServiceWithParameter( instance++ );
}
private int instance;
}
//now everywhere you need ServiceWithParameter:
[Import]
ServiceWithParameterFactory serviceFactory;
var instanceA = serviceFactory.Instance(); //instanceA.a = 0
var instanceB = serviceFactory.Instance(); //instanceB.a = 1
A more extensible way is telling the container you have a factory and an example is presented here: http://pwlodek.blogspot.com/2010/10/mef-object-factories-using-export.html

Related

Generating complex types with all properties equivalent

Does AutoFixture have a facility to create multiple instances of a given type with all the same data? My classes are not serializable and I need two models which are not reference equivalent, but instead have matching properties.
public class Foo
{
// Many more properties and similar models needing the same semantics.
public string Name { get; set; }
}
var a = fixture.Create<Foo>();
var b = fixture.Create<Foo>();
Assert.False(ReferenceEquals(a, b));
Assert.Equal(a.Name, b.Name);
I don't think that AutoFixture can do this, but Albedo can. While this is only proof-of-concept code, it should illustrate the general idea, I hope.
Create a new class, deriving from ReflectionVisitor<T>:
public class PropertyCopyVisitor<T> : ReflectionVisitor<T>
{
private readonly T source;
private readonly T destination;
public PropertyCopyVisitor(T source, T destination)
{
this.source = source;
this.destination = destination;
}
public override IReflectionVisitor<T> Visit(
PropertyInfoElement propertyInfoElement)
{
var pi = propertyInfoElement.PropertyInfo;
pi.SetValue(this.destination, pi.GetValue(this.source));
return this;
}
public override T Value
{
get { return this.destination; }
}
}
The pivotal part of the implementation is the Visit overload where it uses Reflection to copy each property from source to destination object.
Since this implementation mutates destination, the Value property is never used, but it has to be there because it's abstract in ReflectionVisitor<T>...
You can now write your test as:
var fixture = new Fixture();
var a = fixture.Create<Foo>();
var b = fixture.Create<Foo>(); // Or just create a new, empty Foo...
// This copies all properties from a to b:
new TypeElement(typeof(Foo)).Accept(new PropertyCopyVisitor<Foo>(a, b));
Assert.False(ReferenceEquals(a, b));
Assert.Equal(a.Name, b.Name);
Here, I still used fixture to create b, but you don't have to do that, because all properties are going to be overwritten anyway. If Foo has a parameterless constructor, you could instead simply use new Foo(); it'd make no difference.
This proof-of-concept explicitly only copies properties. If you need to copy fields as well, you'll have to override the appropriate Visit method as well. Furthermore, if the objects in question take constructor arguments, you'll need to deal with those explicitly as well.
If you find it tedious to write new TypeElement(typeof(Foo)).Accept(new PropertyCopyVisitor<Foo>(a, b));, I'm sure you can figure out a way to write a helper method around it.
As an additional note, PropertyCopyVisitor doesn't have to be generic, because it doesn't actually use the T type argument for anything. I just like the type safety that this gives the constructor...

Use of Wrapper class for deserialization in callout?

I found the following use of a wrapper class, and was wondering if it is a good practice or whether its just duplication of code for no reason.
//Class:
public class SomeClass{
public Integer someInt;
public String someString;
}
//Callout Class:
public class CalloutClass{
public SomeClass someMethod(){
//...code to do a callout to an api
SomeClass someClassObj = (SomeClass)JSON.Deserialize(APIResponse.getBody(), SomeClass.class);
return someClassObj;
}
}
//Controller:
public class SomeController {
public SomeController(){
someClassObj = calloutClassObj.someMethod();
SomeWrapper wrapperObj = new SomeWrapper();
for(SomeClass iterObj : someClassObj){
wrapperObj.someWrapperInt = iterObj.someInt;
wrapperObj.someWrapperString = iterObj.someString;
}
}
public class someWrapper{
public Integer someWrapperInt{get;set;}
public String someWrapperString{get;set;}
}
}
The wrapper class "someWrapper" could be eliminated if we just use getters and setters ({get;set;}) in "SomeClass."
Could anyone explain if there could be a reason for following this procedure?
Thanks,
James
My assumption (because, code in controller is extra pseudo) is
SomeClass is a business entity, purpose of which is to store/work with business data. By work I mean using it's values to display it (using wrapper in controller), to calculate smth in other entities or build reports... Such kind of object should be as lightweight as possible. You usually iterate through them. You don't need any methods in such kind of objects. Exception is constructor with parameter(s). You might want to have SomeObject__c as parameter or someWrapper.
someWrapper is a entity to display business entity. As for wrapper classes in controllers. Imagine, that when you display entity on edit page and enter a value for someWrapperInt property, you want to update someWrapperString property (or you can just put validation there, for example, checking if it is really Integer). Usually, as for business entity, you don't want such kind of functionality. But when user create or edit it, you may want smth like this.

Silverlight Unit Testing multiple initializations with same tests

I have an object with lots of properties that I would like to test. I have written a TestMethod for each property, but the problem is that many of the properties manipulate the others when they are set. What I need is to be able to set up my test object, manipulate one of the variables, run the tests, reset the object to its original state, then repeat the process. That way, I can avoid having so much redundancy.
I looked into using a Data Driven approach (which is a perfect solution to this problem), but that doesn't seem to be available with the Silverlight Test Framework, since I can't find a way to use the DataSource attribute. I thought about trying to see if I could get access to the DataSource through the traditional MSTest framework, but alas, I only have Visual Studio Express.
I've thought to try to look into creating a custom test harness to see if that could solve this problem, but I thought I'd ask around for suggestions first.
Maybe I should just suck it up and write up all of the different configurations as separate TestInitialize Methods and comment out the ones I don't need as I go.
Any help would be greatly appreciated.
Update/Clarification:
Here is an example of how the object to be tested works. Say you have a shape with a position coordinate and coordinates for each side. When you Update the coordinates of the position or one of the sides, all other coordinates must be updated as well.
This is the functionality that is under test. What I would like to do is be able to set up multiple initializations (through ClassInitialize or what have you) where I would set up the initial value of my object and a mock containing the expected test results, then alter one of the properties in question. Something like this (this is for illustration only, so please ignore any poor practices xD):
// class under test (mock has the same properties & constructor)
public class MySquare
{
public Vector2 XYPosition;
public int Width;
public int Height;
public float TopSidePosition;
public float RightSidePosition;
...
public MySquare(float x, float y, int width, int height)
{
// set up all properties
}
}
// test object container
public class Container
{
public static MySquare square;
public static MySquareMock squareMock;
}
// desired test class initializations (it would be nice to be able to run each of these
// as well as the TestMethods and then reset to the next TestSetupClass)
[TestClass]
public class TestSetupClass1
{
[ClassInitialize]
public void SetupTest()
{
// set up initial value and expected result
Container.square = new MySquare(0, 0, 5, 5);
Container.squareMock = new MySquareMock(1, 1, 5, 5);
Container.square.XYPosition = new Vector2(1, 1);
}
}
[TestClass]
public class TestSetupClass2
{
[ClassInitialize]
public void SetupTest()
{
// set up initial value and expected result
Container.square = new MySquare(0, 0, 5, 5);
Container.squareMock = new MySquareMock(1, 0, 5, 5);
Container.square.RightSidePosition = 6;
}
}
// test methods
[TestClass]
public class TestMethods
{
[TestMethod]
public void TestPosition()
{
Assert.AreEqual(Container.squareMock.XYPosition, Container.square.XYPosition);
}
[TestMethod]
public void TestTopSidePosition()
{
Assert.AreEqual(Container.squareMock.XYTopSidePosition, Container.square.TopSidePosition);
}
// test method for each property
}
I didn't find a completely automated way of achieving my original goal, but I did come up with something pretty easy.
First, I created a singleton TestManager class to handle nearly all of my test setup, so that I only need one line in my MainPage (the test page) class. Within the TestManager, I added a string variable that I assign a name of a TestSetup class too from the MainPage.
Then, I created another TestClass called TestSetupClass and gave two static fields:
private static Type childType;
private static TestSetupClass childInstance;
In its constructor, I compare the underlying type to the class name specified in the TestManager and set the childType and childInstance if they match:
Type thisType = GetType().UnderlyingSystemType;
if (thisType.Name.Equals(TestManager.Instance.SetupClassName))
{
childType = thisType;
childInstance = this;
}
Next, I added a virtual method to the TestSetupClass with an AssemblyInitialize attribute. All of my setup classes inherit from TestSetupClass and override this method. Within the method, I use the childType to get MethodInfo for the child's overridden implementation of the method and invoke it using the childInstance:
MethodInfo childSetup = childType.GetMethod("Setup");
childSetup.Invoke(childInstance, null);
And voila! When you want to run a specific setup before running all the tests, you just specify its class name in the MainPage using the TestManager.
I know there are a few more places where I could have made this better, but it works, so what can you do.

C# setting form.visible = false inside a method?

hi i have this lines of code that i cant make it work
the goal is simple setting the form1 to visible = false
public static void DoActions(string Cmd){
if(Cmd == true)
{
MainForm.Visible = false;
}
}
but i keep on having this error
An object reference is required for
the non-static field, method, or
property
usually i set the called methond to static.. so the error will go away
but on this case how do i do it?
thanks for any help guys
'System.Windows.Forms.Control.Invoke(System.Delegate)'
This is happening because DoActions is a static method rather than an instance method, however MainForm is an instance field / property. The distinction is that instance methods operate on an instance of the class on which they are defined, wheras static methods do not.
This means that wheras instance methods are able to access properties, fields and methods of their containing class through the this keyword, for example:
// Instance field
Form1 MainForm;
void InstanceMethod()
{
Form1 frm = this.MainForm;
}
You cannot do the same thing from inside a static method (think about it, what instance would it operate on?). Note that C# will implicitly assume the use of the this keyword in places where it makes sense (so the above example could have been written as Form1 frm = MainForm).
See C# Static Methods for an alternative explanation of static vs instance methods (this is an important concept in object oriented programming that you should take the time to understand properly).
In your example you probably want to change DoActions to an instance method (by removing the static declaration):
public void DoActions(string Cmd)
{
if(Cmd == true)
{
this.MainForm.Visible = false;
}
}
This will allow it to access the instance MainForm field / property, however this may cause problems elsewhere in your code in places where you attempt to call DoActions from another static method without supplying an object instance.
Set form opacity and showintaskbar property in property window:
this.Opacity = 0;
this.ShowInTaskbar = false;
Your method is static - and so cannot access MainForm.
Make your method non-static if it is not required to be so.
public void DoActions(string Cmd)
{
if(Cmd == true)
{
MainForm.Visible = false;
}
}
If it is required, then create a static field in your class and ensure it is set before this method runs.

Winforms: access class properties throughout application

I know this must be an age-old, tired question, but I cant seem to find anything thru my trusty friend (aka Google).
I have a .net 3.5 c# winforms app, that presents a user with a login form on application startup. After a successful login, I want to run off to the DB, pull in some user-specific data and hold them (in properties) in a class called AppCurrentUser.cs, that can thereafer be accessed across all classes in the assembly - the purpose here being that I can fill some properties with a once-off data read, instead of making a call to the DB everytime I need to. In a web app, I would usually use Session variables, and I know that the concept of that does not exist in WinForms.
The class structure resembles the following:
public class AppCurrentUser {
public AppCurrentUser() { }
public Guid UserName { get; set; }
public List<string> Roles { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
}
Now, I have some options that I need some expert advice on:
Being a "dumb" class, I should make the properties non-static, instantiate the class and then set the properties...but then I will only be able to access that instance from within the class that it was created in, right?
Logically, I believe that these properties should be static as I will only be using the class once throughout the application (and not creating new instances of it), and it's property values will be "reset" on application close. (If I create an instance of it, I can dispose of it on application close)
How should I structure my class and how do I access its properties across all classes in my assembly? I really would appreciate your honest and valued advice on this!!
Thanks!
Use the singleton pattern here:
public class AppUser
{
private static _current = null;
public static AppUser Current
{
get { return = _current; }
}
public static void Init()
{
if (_current == null)
{
_current = new AppUser();
// Load everything from the DB.
// Name = Dd.GetName();
}
}
public string Name { get; private set; }
}
// App startup.
AppUser.Init();
// Now any form / class / whatever can simply do:
var name = AppUser.Current.Name;
Now the "static" things are thread-unsafe. I'll leave it as an exercise of the reader to figure out how to properly use the lock() syntax to make it thread-safe. You should also handle the case if the Current property is accessed before the call to Init.
It depends on how you setup your architecture. If you're doing all your business logic code inside the actual form (e.g. coupling it to the UI), then you probably want to pass user information in as a parameter when you make a form, then keep a reference to it from within that form. In other words, you'd be implementing a Singleton pattern.
You could also use Dependency Injection, so that every time you request the user object, the dependency injection framework (like StructureMap) will provide you with the right object. -- you could probably use it like a session variable since you'll be working in a stateful environment.
The correct place to store this type of information is in a custom implementation of IIdentity. Any information that you need to identify a user or his access rights can be stored in that object, which is then associated with the current thread and can be queried from the current thread whenever needed.
This principal is illustrated in Rocky Lhotka's CLSA books, or google winforms custom identity.
I'm not convinced this is the right way but you could do something like this (seems to be what you're asking for anyway):
public class Sessions
{
// Variables
private static string _Username;
// properties
public static string Username
{
get
{
return _Username;
}
set
{
_Username = value;
}
}
}
in case the c# is wrong...i'm a vb.net developer...
then you'd just use Sessions.USername etc etc

Resources