Prism event aggregator - ThreadOption.UIThread worked in v4 but not v6 - prism

I've been using Prism 4.1 and have numerous classes that subscribe to events (usually in their constructor) using the IEventAggregator and the ThreadOption.UIThread option.
I've now upgraded to Prism 6 but when I run my application it falls over on one such line with an InvalidOperationException. The message is:
To use the UIThread option for subscribing, the EventAggregator must be constructed on the UI thread
The call stack shows that the class in question is being resolved by my DI container (Castle Windsor) hence why it's not on the UI thread. However it all worked fine with Prism 4.1 so what's changed?

It turns out it was down to the way my application was starting up. I was using a "Main" style of entry point, but I needed to move it to the App.xaml OnStartup() instead:
Prism EventAggregator Exception - must be constructed on the UI thread

I doubt it worked before in the sense of "the subscribers were run on the ui thread", rather they were run on a random thread the EventAggregator is created on. In older version of prism, it just didn't care (and ThreadOption.UIThread lied, in a way).
I don't know Castle Windsor that well, but just because being resolved by the DI framework doesn't mean being created on a different thread. To be on the safe side, resolve the EventAggregator once in InitializeModules in the boot strapper, so that it gets created on the ui thread.
With Unity it would look like this:
internal class Bootstrapper : UnityBootstrapper
{
protected override void InitializeModules()
{
Container.Resolve<IEventAggregator>();
base.InitializeModules();
}
}

Related

Prism use of discovered service

Suppose a Prism version 8 WPF module has a ViewModel which needs to call on a service.
the service implements IService, but there exists a number of implementations of this service. Each implementation is a file (class library), possibly as a IModule (see below).
The user shall be able to configure which file to use either by configuration or by a folder's content.
Obviously(?) I am thus thinking of Module discovery by creating the right type of ModuleCatalog while "bootstrapping" the application and the service could thus be contained in this module.
If the call is a void call ("fire-and-forget") I guess I could simply use EventAggregator (implementing the service as an observer), however the call returns a value.
What is the best approach solving this?
(I would like to avoid writing my own assembly "discovering/loading" of some kind of a swappable service implementation dll file)
If you can inject IEventAggregator, you can inject IService, can't you?
If no module registered an implementation, you'll get an exception. If more than one module did, the last one wins (with unity as container, at least).

How to use Autofac to initialize your own components?

I would like to use Autofac IOC container in my bot application (based on BotFramework).
I can see that framework itself already uses it.
But I can't figure out how to do it gracefully... I don't want to resolve my components on every post invocation (it will slow down my post method execution).
I appreciate if you share code snippets with your solutions.
Thanks in advance!
You can use the Autofac container being used in the framework in the Global.asax and perform your own registrations.
The key code pieces are:
var builder = new ContainerBuilder();
// perform your registrations on the builder
// update the container being used by the framework
builder.Update(Conversation.Container);
For a real implementation of this, you could take a look to the ContosoFlowers sample where you will see that a Module is used to register the application specific components. Here is the Global.asax and here the actual module.

Synchronizing between a framework listener and events during startup

OSGi version 5, via Felix version 4.4.1.
I'm embedding the framework, purely via the OSGi API, nothing Felix-specific. So, I use the SPI to obtain the framework class name, create an instance, and init it.
Then I install bundles, start all the bundles, and start() the framework.
Now, if something goes wrong, a framework event will be delivered. Felix delivers these on a separate thread. How can I synchronize event delivery with start() returning? FrameworkStartLevel.setStartLevel has an option to accept listeners and guarantee that they will be called before it returns, but that only helps if I'm going to bump the start level above 1. I guess I could set all the bundles to start level 2, and thus defer their startup until I made a call to bump the level to 2, and thus get the desired sync. Is there any simpler way to just leave everything at level 1?

Two Autofac containers competing in a single webrequest

A bit of a strange situation: I'm developing an ASP.NET MVC 3 application that uses Autofac as its IoC container and that can be dropped into any existing MVC or WebForms application.
Everything works fine, except when the other application also uses Autofac. I've created a custom DependencyResolver wrapper that combines my application's AutofacDependencyResolver with DependencyReolver.Current of the other application (when set). Resolving of components just fails sometimes although I can see in the debugger that everything is properly registered.
I suspect that both inner resolvers are competing for a spot in the HttpContext.Items collection, but I can't get my finger behind the exact issue.
What would be the proper way to handle this situation?
You could isolate the configuration into a module. When you integrate one application into the other, register the module.

Ioc container placement within enterprise application

I've been looking into Ioc containers and AOP recently, and I'm pretty amazed by the concepts. I'm struggling however to decide how and where to implement the container.
The articles below suggest implementing the container in the 'application entry point':
Best Practices for IOC Container
IOC across visual studio projects?
Not understanding where to create IoC Containers in system architecture
Now - my thought-experiment application will consist of multiple visual studio projects ( one for data access, winforms application ). And let's say I want to use AOP for logging with Log4net, and so I setup log4net in the Ioc container.
So WinForms application in entry point, that's where Ioc container should go.
Here's the question: if I want to log stuff in my data access project/layer, should I add a
reference to my winforms application, get the ioc container from there, get the log4net instance out of it and use it for logging?
That would mean my data-layer depends on winforms application, that can't be right. How about I put the container is something like a 'Common' project within the solution. That way, all related projects (Data access/winformsa etc.) can access the container.
What is the right way to go here?
Your application's Composition Root would be the Windows Forms project. This is the only project which should have a reference to a DI Container.
In all other projects, dependencies should be injected via Constructor Injection. All decent DI Containers understand this pattern and use it to Auto-wire dependencies from the Composition Root.
I've abstracted my container into a separate assembly that all other assemblies / projects depending on its services reference. The container project has just a single class and - more or less - a single method:
public class MySpecialContainer
{
public T Resolve<T>() { // ... Get stuff from the IoC container }
}
The container build would either occur in MySpecialContainer's ctor or just add another method like Initialize() or some such.
The only problem is this approach broke down for me when I used Autofac and had both a Windows Service and ASP.Net project needing the container. Each had its specific requirement for scoped-lifetime services: Windows Service - PerLifetimeScope, ASP.Net - PerHttpRequest. I guess I could've passed in an argument into MySpecialContainer that denoted which scenario to configure for but I decided just to take on an Autofac dependency directly.
The good news is, if you stick to ctor injection, then you can very easily swap out various container implementations - Autofec, Ninject, StructureMap, etc.

Resources