Instantiating a new type with MEF - wpf

I am using CompositionInitializer.SatisfyImports(this) from Glen Block with a WPF application using Prism 4.1 and Prism's MEFExtensions.
I have used this many times before and not had a problem, but every once in a while when I call SatisfyImports(this) and get the following error:
A first chance exception of type
'System.Resources.MissingManifestResourceException' occurred in
mscorlib.dll
Additional information: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure
"System.ComponentModel.Composition.Initialization.Strings.resources"
was correctly embedded or linked into assembly
"Microsoft.ComponentModel.Composition.Initialization.Desktop" at
compile time, or that all the satellite assemblies required are
loadable and fully signed.
If there is a handler for this exception, the program may be safely continued.
Anyone know why I'm getting this error and how to fix it?

The CompositionInitializer approach doesn't work with WPF in some cases, as evidenced by the MissingManifestResourceException above- basically, I think this is saying that one of the imports is failing due to some resource problem of the imported DLL... which you may or may not have any control over.
The better approach (I think) is to use the MEF ExportFactory to instantiate objects for WPF applications rather than the CompositionInitializer:
[Export]
public class OrderController {
[Import]
public ExportFactory<OrderViewModel> OrderVMFactory {get;set;}
public OrderViewModel CreateOrder() {
return OrderVMFactory.CreateExport().Value;
}
}
Worked for me anyways.
I do have some questions about memory management and the export factory, but that's another post :)

Related

How do I implement IActivationForViewFetcher for a child UserControl?

I've just added ReactiveUI to an existing code base. Of course, for the first control I tried it with I hit a snag. I'm using it with a UserControl embedded in a TabControl. The code looks something like this:
public partial class TabPageControl : UserControl, IViewFor<TestViewModel>
{
public TabPageControl()
{
InitializeComponent();
ViewModel = new TestViewModel();
this.WhenActivated(dispose =>
{
dispose(this.Bind( ... ));
dispose(this.BindCommand( ... ));
});
}
}
When I run the app, I get the following error message:
Don't know how to detect when TabPageControl
is activated/deactivated, you may need to implement
IActivationForViewFetcher
So, how do I implement IActivationForViewFetcher? I'm not sure what I'm supposed to do with GetAffinityForView. I'm assuming in GetActivationForView I need to check to see if the UserControl is the currently visible inside the TabControl?
Although I would like to understand how to implement the methods for IActivationForViewFetcher (especially the part where I identify that a control is in the VisualTree) - the real cause of my problem was that my main assembly didn't have the appropriate references (the controls are in a class assembly).
I'm assuming (because I've skimmed the ReactiveUI source) ReactiveUI.Winforms.Registrations needs to be instantiated by the main assembly - which includes registering ActivationForViewFetcher.
Incidentally, the class library is written in C# and the main assembly is VB.NET. So I'm not sure whether this contributed to the problem.
At least it's working now!
I don't if this will ever help anybody, since this thread is so old.
What solved my issue was having ReactiveUI.WPF,ReactiveUI.WinForms, CefSharp.WPF and CefSharp.WinForms NuGet references on all the projects/plugins that were running on the App.
My suspicion is that when ReactiveUI/CefSharp is initialized and it doesn't contain all the info/files it needs, it will not possible to add them later on runtime. But this is just guessing based on my experience.
I know it's an old thread, but just to save other developers time when facing this problem.
My solution was to add the following code in the entrypoint of the project that makes use of ReactiveUi and ReactiveUi.Wpf.
var reactiveUiWpfName = typeof(ReactiveUI.Wpf.Registrations).Assembly.FullName;
Assembly.Load(reactiveUiWpfName);
Of course, it was just required because I couldn't reference ReactiveUi or ReactiveUi.Wpf in my application startup project due to the project specifications, otherwise this error wouldn't appear anyway.
(Please, observe that, in your case you should use ReactiveUi.Winforms in the places I've used ReactiveUi.Wpf)

Why is my app error in design time, but not run time?

I am creating a WPF app using Ninject. I created my bindings in Application.xaml.vb and then store the kernal in Application.Current.Properties so I'll have those bindings to resolve as needed.
I am getting this error at design time: Cannot create an instance of "MainUserViewModel". If I remove the code out of my MainUserViewModel's constructor, I don't get the error.
Public Sub New()
'IoC is the kernel
Dim repository = IoC.Get(Of IUserRepository)()
_users = New ObservableCollection(Of User)(repository.GetAll())
End Sub
However, when I run the code, my the error goes away and my view populates just fine from _users. I would think if there's an error, the code wouldn't compile and (appear to) work.
I've removed every other piece of my VM and added them all back in. The error only appears when I use that line of code.
Can anyone explain why this is happening? I've checked the repository and all of the expected data is there.
EDIT
Is it possible that the error is occurring in the XAML due to the dependencies not being able to be resolved since it wasn't running? So, as far as it knows, that observable is never being initialized?
Probably the bindings for IoC are not initialized at design time and IoC.Get(Of IUserRepository)() is throwing NinjectActivationException thus the viewmodel cannot be created by designer.
I would move the init code from constructor e.g. to some lazy loaded property.
// sorry for C#
private ObservableCollection<User> _users;
public ObservableCollection<User>
{
get
{
if(_users == null){
repository = IoC.Get<IUserRepository>();
_users = new ObservableCollection<User>(repository.GetAll());
}
return _users;
}
}
However, it is not a good idea to wire up all your code with hard coded dependency on IOC container - it is commonly called "service locator anti-pattern". Give a try to approach in this link: Ninject constructor injection in WPF => there is also use of service locator, which will be responsible for creating your ViewModels, but the dependency on IoC is elegantly hidden in one place - composition root.

How to create WPF/Silverlight module utilizing prism but also that can be embedded in non-prism applicationss

I want to have create a WPF or Silverlight module which cannot only be utilised by Shell's bootstrapper, but also can be embedded in non-PRISM applications.
In short is there a way PRISM module can be intialised from module itself rather than initialsing from Shell?
Ulimate goal is to have WPF/Silverlight PRISM module, which can be initialsed by non-PRISM applications.
There is no barrier to this.
The IModule interface has a single, parameterless void method: Initialize().
A non-prism application can initialize the module by calling that method. That's it.
If the other application has a different plugin system, with a different interface, your module can implement that interface as well, and the body of whatever initialization method that interface uses can simply call Initialize(), or vice versa.
For example:
public interface IMyPluginModule
{
void StartModule();
}
public class MyModule : IModule, IMyPluginModule
{
public void Initialize()
{
// actual initialization code here
}
public void StartModule()
{
Initialize();
}
}
It's a little more complicated than it appears at first glance, but it is doable. I don't know if you are using Prism 4 yet, but if so, Microsoft actually provides guidance for this scenario:
http://msdn.microsoft.com/en-us/library/ff921109(v=PandP.40).aspx
There is a bit of project manipulation you need to do to get two projects running side-by-side. There is a sample included with Prism v4 called "MultiTargeting" if you need to see a working sample.
Your question regarding to allowing a module to be initialized by itself, rather than having the orchestrating Shell / Bootstrapper is the wrong approach, however. Essentially what you would have would be two shells... one WPF and one Silverlight. Take a look at the samples and see what you think.
Hope this helps.

Using Moq at Blend design time

This might be a bit out there, but suppose I want to use Moq in a ViewModel to create some design time data, like so:
public class SomeViewModel
{
public SomeViewModel(ISomeDependency dependency)
{
if (IsInDesignMode)
{
var mock = new Mock<ISomeDependency>();
dependency = mock.Object; // this throws!
}
}
}
The mock could be set up to do some stuff, but you get the idea.
My problem is that at design-time in Blend, this code throws an InvalidCastException, with the message along the lines of "Unable to cast object of type 'Castle.Proxies.ISomeDependencyProxy2b3a8f3188284ff0b1129bdf3d50d3fc' to type 'ISomeDependency'." While this doesn't necessarily look to be Moq related but Castle related, I hope the Moq example helps ;)
Any idea why that is?
Thanks!
I'm having a similar issue, except that the cast is coming from a dynamically generated assembly (Blend_RuntimeGeneratedTypesAssembly) type that is masquerading as one of my types.
For no apparent reason.
Which is driving me CRAZY.
I used to think that I needed to do this sort of trick but after much experiementing and searching about, discovered that Blend 4 now can create design time sample datacontexts based on an existing class.
This effectively gives you a dummy class that looks just like your VM class so that you can add your binding etc.
It works well enough that this is the technique we now recommend.
A possible disadvantage with this is that if you need your real VM to perform some sort of interactivity then the proxy of course can't do that - you'd have to manually change values, or swap to another design time object. But in practice, I've rarely encountered this scenario. Most of the time, you set the state of the VM and then take ages getting the look right.
Update: released on github: https://github.com/GeniusCode/GeniusCode.Components.DynamicDuck
I also ran into a similar problem when trying to use castle to mock viewmodels at design time. We wrote our own msil duck / mock library, and it works well for that purpose.
I blogged about it here: http://blogs.geniuscode.net/JeremiahRedekop/?p=255
We are working to release the library under MS-PL and deploy on GitHub.

Subclassing TDataset: InternalRefresh

What are you supposed to do in InternalRefresh when you subclassing TDataset in Delphi?
Fetch the data from the database again. The public interface to this is TDataSet.Refresh.
Note that TQuery's override of this just throws an exception. There's not a strict requirement to do anything useful here, if you don't care about supporting Refresh.

Resources