Caliburn.micro calling navigationService.UriFor on dynamic type - caliburn.micro

I'm trying to allow some navigation in Caliburn.Micro in a bit of a dynamic way (viewModels won't be known at design time).
This code obviously works
navigationService.UriFor<DatabasesViewModel>().Navigate();
However, with what I'm trying to do, I won't know the view model ahead of time. Instead I'll only have the Type of the view model.
I've been trying to use reflection to get the generic method, but I'm to able to get the UriFor method via GetMethod or GetMethods. Any ideas how this can be accomplished.

Your problem is not directly related to Caliburn.Micro but how to call generic methods with reflection in C#.
There are already quite a few and very good questions about this on SO:
How do I use reflection to call a generic method?
However your case is a little bit special because the UriFor<T> method defined as an extension method by Caliburn in the NavigationExtensions class
So you need some extra steps and start from the NavigationExtensions type before you can call Navigate:
//Create the UriFor Method for your ViewModelType
var navigationExtension = typeof(NavigationExtensions);
var uriFor = navigationExtension.GetMethod("UriFor");
var genericUriFor = uriFor.MakeGenericMethod(yourViewModelType);
//Invoke UriFor: an instance of UriBuilder<T> is returned
var uriBuilder = genericUriFor.Invoke(null, new[] {navigationService});
//Create and Navigate on the returned uriBuilder
var navigateMethod = uriBuilder.GetType().GetMethod("Navigate");
navigateMethod.Invoke(uriBuilder, null);

Related

What do you call the method DI uses to populate a model?

Implementations of IHost like the generic host do dependency injection. You populate a services collection with helper methods like this
IConfigurationSection section;
section = config.GetSection("SectionName");
services.Configure<SectionModel>(section);
Inside the Configure helper method some magic creates an instance of SectionModel and populates it from the IConfigurationSection object.
What is that called? I need to do it in the absence of the DI and while I'm sure rummaging through Microsoft source code would probably yield answers I could rummage a lot faster armed with the name of the method that does it.
More than likely they just use reflection, but I'd prefer not to implement this myself and have potentially divergent behaviour.
According to documentation this is called Bind and is surfaced on IConfigurationSection.
First you create the config section and model objects, then you call Bind like so
var sectionModel = new SectionModel();
config.GetSection("SectionName").Bind(sectionModel);
#Nkosi comments
The same can be done using
var sectionModel = config.GetSection("SectionName").Get<SectionModel>();
This is a more elegant expression of the same solution using generics.

Copying an instance of a class

Ok, ObjectUtil.copy is a good technique for copying Objects. But after having a lot of problems using it to copy other classes, I guess it is not the solution I'm after.
How would you approach the copying/cloning of instances of a class that you've defined? Maybe defining a function withing the class to copy it?
It is cool that most variables are passed by reference in flex, but sometimes is annoying not having control over this (sorry, I'm too used to plain C).
Thanks!
UPDATE:
To be more precise, as I can't make the ObjectUtil.copy() work with a custom class is... is there a way to copy, by using serialization, a custom class? Did you use successfully a ByteArray copy with a custom class?
Thanks for all the replies.
If you determine that implementing a clone interface is not the correct approach in your situation, I suggest looking at the ByteArray object. I haven't used it myself, but it appears to give you all the control you should need over individual bytes. You can reading and writing from and to any object.
Senocular does a quick overview of it here.
function clone(source:Object):* {
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
Good luck!
ObjectUtil.copy uses ByteArray internally to create a copy. In order for the copy to be successful, ByteArray requires that the flash player will be aware of you custom class. You do that by registering your class using the global registerClassAlias method.
For example:
//one time globally to the application.
registerClassAlias(getQualifiedClassName(CustomClass), CustomClass);
//then
var c1:CustomClass = new CustomClass();
c1.name = "customClass";
var c2:CustomClass = ObjectUtil.copy(c1);
trace(ObjectUtil.toString(c1))
trace(ObjectUtil.toString(c2))
If you have control over the whole class hierarchy, I recommend implementing a clone() interface in every class. It's tedious, but will pay off as complexity increases.
(Forgive me if the syntax is a bit off, it's been a while)
// define a "cloneable" interface
public interface ICloneable {
function clone() : Object;
}
For every class, implement the method...
public class MyClass1 implements ICloneable {
...
public function clone() : Object {
var copy:MyClass1 = new MyClass1();
// copy member variables... if it is a user-defined object,
// make sure you call its clone() function as well.
return copy;
}
}
To create a copy of the object, simply invoke the clone() function.
var copy:MyClass1 = original.clone();
As a side note, both Java and .NET seem to have adopted the clone methods on their base Object classes. I know of no analogous method for ActionScript's Object class.
Two common idioms:
a clone method
a copy constructor
Both of these let you define what exactly making a copy means--you may want some things copied shallowly and others deeply.

Flex: Configure AMF serialization warnings?

I have been trying to test my application to make sure that all the important classes can serialize/reload themselves properly (especially those which implement IExternalizable):
[Test]
public function testMyObjectSerialization():void {
var myobj:MyObject = new MyObject();
var ba:ByteArray = new ByteArray();
ba.writeObject(myobj);
ba.position = 0;
var loadedObj:MyObject = ba.readObject();
assertMyObjectEqual(myobj, loadedObj);
}
And I would like to be warned when I try to serialize a strongly-typed object which does not have a [RemoteClass] set (because that almost certainly represents a bug in my code).
So, is there any way to configure the AMF serializer to give warnings?
Also, it seems like this might be possible using services-config.xml… But the documentation seems to imply that services-config is channel-level, and I'd really like it if my unit tests could run without talking to the server (and I'm not using LCDS, so a bunch of the services-config wouldn't apply to me anyway).
There is no way to configure the native AMF serialization/deserialization from the Flash Player to give you warnings if [RemoteClass] or any other metadata is set or not.
However you can write your own class to do that - you can register all the objects in a list and check for [Remote] using flash.utils.describeType. Or use a wrapper over writeObject which check for the [Remote] metadata.

Is () requested for invoking a Flex ActionScript constructor?

In Flex ActionScript, a new object can be instantiated via the parameterless constructor with or without (). Example:
var array:ArrayCollection = new ArrayCollection()
or
var array:ArrayCollection = new ArrayCollection
Is there a difference between the two? Is one preferred over the other?
I think there is no difference functionally, but I like having the () just because of convention.
Interesting point. Until your question I had never even tried passing a class to the "new" operator without a closure to indicate I was calling the constructor. I just tried it without and it works, but I wouldn't feel comfortable doing it that way.
I don't know of any differences between these two ways of instantiating an object, however convention would lean towards using (). Think about when you instantiate an object that requires parameters sent into the constructor var e:Event = new Event('EventType');, having the parentheses even when left empty tells you that nothing is getting passed in.
if your not going to do anything with the constructor, then you don't even need to go that far:
var array:ArrayCollection;
would declare your variable just fine.
There is probably no real difference as the constructor is probably a magic method that will automagically be called when the class is called.

DLR and reflection

Everywhere I read about the new DLR in .net 4, they say that a good use for it is reflection, and the code snippet always shown is something like
dynamic d = GetSomeObject();
d.DoSomething();
d.SomeMember = 1;
What does GetSomeObject() look like? I can't find anywhere that explains that.
I understand that it can be anything, but in the context of reflection what is it? Is it the assembly? an instance of a type?
The return type of GetSomeObject() will be an instance of some type. For example, here's what it might look like:
public Customer GetSomeObject() {
return new Customer("John", "Doe", 12345);
}
And then the code would say:
dynamic customer = GetSomeObject();
string s = customer.FirstName;
// now the "s" variable would have "John" in it
The GetSomeObject() can return anything. It might return a Customer object or a Product. And it doesn't matter! The idea is that when the variable is declared as being dynamic that when you call a method or a property, as you have shown, the compiler will generate code that uses Reflection to try and call the method or property. If they exist then the calls will succeed. If not then you'll get an error at runtime.
In the general case this example is just simplifying the usage of Reflection by having the compiler generate the code for you.
Having said that, if the Customer or Product object implement IDynamicObject themselves then they can do far more advanced stuff.
What you are describing is the duck-typing aspect of dynamic (there are other facets). The answer is that it could be anything:
a true dynamic object (IDynamicObject)
any regular object, via reflection
A useful example (for reading properties, at least) might be an anonymous type; it could also be a COM object, for example - or (in Silverlight) an object in the html DOM. Or it could be your vendor's Customer object that doesn't implement any common interface, but is remarkably like your own InternalCustomer object. Heck, it could be an IronPyton object.
Well, GetSomeObject() could, for instance, return an instance of type _ComObject. That's one of the primary reasons of having it dynamic, I think.
I think that it's more interesting, as far as dynamic, DLR and reflection concerns, to see what happend in line 2 for instance.
using dynmic you go like this
dynamic d = GetSomeObject();
d.DoSomething();
while with reflection it's a bit more noisy
var d = GetSomeObject();
var mi = d.GetType().GetMethod("DoSomething");
mi.Invoke(d,mi);
As I see it, the first one is more elegant and we are talking about an argument less method, things can go really crazy when you are interoping with COM or APIs with long signature methods. I been there ;)

Resources