Is the IoC container allowed to use the Messenger/Mediator class? - mvvm

I'm new with IoC, and i'm wondering if best practices allow the container to use the mediator class, for example MVVM Lite's Messenger. Can the container regiser for and send messages?
Thank you very much!

Your container should not (and doesn't need to), talk to any part of your application. The only point that you should reference your container is at your composition root which is normally in your applications bootstrapper.

Related

Caliburn.Micro, MVVM and Business layer

I'm building a WPF application using MVVM pattern, and Caliburn.Micro is the framework choice to boost up the development.
Different from a conventional MVVM-based application, I add a business layer (BL) below the ViewModel (VM) layer to handle logic for specific business cases. VM is left with data binding and simple conversion/presentation logic. Below BL is an extra Data Access layer (DAL) that encapsulates the Data model (DM) underneath built with Entity Framework.
I'm pretty new to both WPF, MVVM and, of course, know almost nothing about Caliburn. I have read plenty of questions and answers about the Caliburn usage and now trying to use what I've learnt so far in my application.
My questions are:
Does it sound okay with the above layered architecture?
In the application bootstrapper, is it correct that we can register all services that will later be used (like EventAgreggator (EA), WindowManager or extra security and validation services), and also all the concerned VMs? These should be injected into VM instances via constructors or so (supposed I'll be using SimpleContainer). So from any VM that are properly designed and instantiated, we can have these services ready to be used. If I understand correctly, Caliburn and its IoC maintain a kind of global state so that different VMs can use and share it.
Navigation: I know this topic has been discussed so many times. But just to be sure I'm doing the right way: There'd be a ShellViewModel acting as the main window for the whole application with different VMs (or screens) loaded dynamically. Each VM can inherit either Screen or ViewModelBase or NotifyChangedBase. When I'm in, let's say, VM A and want to switch to VM B. I'd from inside VM A send a message (using EA) to the ShellViewModel, saying that I want to change to B. ShellViewModel receives the message and reloads its CurrentViewModel property. What should be a proper data structure to maintain the list of VMs to be loaded? How can stuffs like Conductor or WindowManger come into the place?
Can/Should Caliburn in one way or another support the access to the database (via EF). Or this access should be exposed to VM and/or BL only?
Thanks a lot!
Different from a conventional MVVM-based application, I add a business layer (BL) below the ViewModel (VM) layer
That's the standard case. ViewModels can't/shouldn't contain business logic which is considered to be part of the Model (Model in MVVM is considered a layer, not an object or data structure) in the MVVM. ViewModel is for presentation logic only.
Yes, as long as your Business (Domain) Layer has no dependency on the DAL (no reference to it's assembly). Repository interfaces should be defined in the Business Layer, their implementations in the Data Access Layer.
Yes, Bootstrapper is where you build your object graph (configuration the IoC container).
Registering ViewModels: Depends on IoC framework. Some frameworks let you resolve unregistered types, as long as they are not abstract or interfaces (i.e. Unity). Not sure about Caliburn, haven't used it. If the IoC supports it, you don't need to register them.
One possible way to do it. I prefer navigation services though, works better for passing around parameters to views and windows that are not yet instantiated and you always know there is exactly one objects handling it.
With messages, there could be 0, 1 or many objects listening to it. Up to you
What do you mean with support access to the database? You can use it to inject your repositories and/or services into your ViewModels, other than that there isn't much DB related stuff to it.

How to distribute IOC/DI components over several machines?

I'm maintaining a large application that makes heavy use of StructureMap to load it's components. I'm trying to split the components up so they can run on different machines, connected via network. They already run in different threads, but within the same process (making use of a single StructureMap container).
I'm not sure how to do this. Is it possible to have StructureMap automatically create a proxy for all components and use them over network instead of locally? What changes to the components are needed to make them distributable?
Interesting! Theoretically I guess it is possible, the real underlying question is if you really want to do so, we are talking about a major architectural change.
Disclaimer: I don't know how familiar you are with WCF, I'll attempt to explain very roughly how I imagine it being possible, but consider that if we are talking about this sort of communication over a network you want to use WCF.
Define every interface for the components that you want to use over a network as a WCF service contract
Wrap your components with services and host them somewhere/somehow
Write clients for these services, having them implement your components interfaces
Let StructureMap inject your clients when the code expects a component
While it sounds quite straightforward, a relevant complexity is hiding behind these steps. To name a few potential issues off the top of my head: which components are you going to wrap into services? How easy is wrapping them going to be? Where are you going to host them, how? What about security? Does your logging mechanism need to be adjusted?

CAB: Get service instance without having a reference to WorkItem

Is it possible to get an instance of a service without having a WorkItem context?
I have a some classes that need to access some services, and i'm wondering if it's possible to get those services without explicitly injecting those services in the class.
As all the services are registered in WorkItem or rootWorkItem context its not possible according to the design rules of CAB/SCSF.
Please elaborate why you cannot register the service in WorkItem and get it from there. CAB/SCSF has proposed the best practices to manage an enterprise application, its upto us how much we benefit from it.
But if its really necessary you can have a static class (which can act as service implemented in singleton way) in Infrastructure.Library and refer this assembly in your Business or Functional module to get it.
Its a bad hack but technically doable.

What is the correct way of Instantiate Controller with IoC

I am migrating to ASP.NET MVC 3.
Now I have some ways of resolve controller with IoC.
My controller need a contructor injection parameter for repositories.
Setting DependencyResolver.SetResolver works. But I donĀ“t know if this is correct way or I need to Register a IControllerActivator at my container too.
What you need is a ControllerFactory.Most IOC containers have an existing implementation. If you need a custom one, check this article:
http://develoq.net/blog/?p=144
Update
It's the correct way. DependencyResolver is generic for everything, and you need to register the IControllerActivator in it.
http://bradwilson.typepad.com/blog/2010/10/service-location-pt10-controller-activator.html

Using Castle Windsor to inject IRailsEngineContext

Issue
I am using Castle Windsor as an IoC container in a Castle Monorail project. I would like to inject the current instance of IRailsEngineContext into an object being resolved from the container in a controller.
Context
The object I would like inject the rails context into would be used to wrap the session object for the purpose of retaining the ids of previously viewed records. It would then be referenced to ensure that they aren't viewed again.
Alternate Solutions
I could pass the context to the methods with each call or inject it manually, but it would be nice to inject it directly from the container.
Question
I can't think of a way to inject the context within the container. Is there a way to do this? Does this even make sense?
Container.Register(
Component.For<IRailsEngineContext>()
.UsingFactoryMethod(()=>MonoRailHttpHandler.CurrentContext)
.LifeStyle.Transient
);
IRailsEngineContext - that's from an old version of MonoRail I guess. I'd advise you move to a newer one, the sooner the better.