Bootstrapper design pattern using Caliburn.Micro MVVM framework with IoC-container - c#

The WPF application uses Caliburn.Micro as MVVM framework. CM has it's built in IoC-Container named SimpleContainer, I replaced it with Castle.Windsor container. (But container type does not matter here I guess.) CM uses a Bootstrapper.Configure() method where container can be configured. After that Bootstrapper.OnStartup() method starts application displaying a View for root ViewModel. So container configures before first View appears. In my case container configuration a pretty complex and may cause errors. For example I want to deserialize some XML files from app directory to objects and register them as components in container. So I want to get a SplashScreen to see container configuring progress, and then if all OK, splash disappears, container resolves root item and application starts as expected. If not - problem shown on splashscreen. I can't get in mind how to get a SplashScreenView (binded to SplashScreenViewModel) before I get a configured container. So application divides on "before" and "after" container. How can that issue can be solved? Is there any patterns? Is it OK to partly configure container in Configure and partly somewhere else, after it Resolved some components? Or maybe there is a practic to use container instance "inside" components resolved by another container instance? Thanks.
public class CastleModernUIBootstrapper : BootstrapperBase
{
private WindsorContainer _container;
public CastleModernUIBootstrapper()
{
Initialize();
}
protected override void Configure()
{
_container = new WindsorContainer();
// here components are registered.
// I want perform complex container configuration here,
// but I can't vizualize what happens here.
_container.Register(Component.For<LoadingSplashScreenViewModel>());
// ...
}
// ...
protected override void OnStartup(object sender, StartupEventArgs e)
{
// after we resolving first element from container
DisplayRootViewFor<LoadingSplashScreenViewModel>();
}
}

WPF has a built-in (as in I don't know how it works) Splash Screen. Just use "Add new item" on your project. It does work with Caliburn.
It's only a simple bitmap, but it takes care of the appearance. You can handle your errors as normal data.
You don't want your Splash window to be the Root View anyway.

Related

Winforms IOC Container - Composition Root

I've recently been dabbling a bit with IOC Containers (LightInject in my case).
I've been reading that you should only need to use the container ONCE, on startup, and no where else. This is what I'm struggling to understand. If I can only reference the container in a bootstrap/startup method, how is it possible to resolve what I need, elswhere in the project, or at runtime if the class depends on user input.
So In my Traditional Windows Forms App, on Form Load Say, I would Bootstrap Lightinject as per the below code. It's only an arbitrary example, it's more the premise I need to get my head around.
I might be missing something here entirely, or just not getting it. But how am i supposed to resolve dependancies, If i can't use/not supposed to reference or use Container.GetInstance/Resolve/{Choose IOC Syntax Here}, and only in the composition root.
For Instance, Say I have two buttons and a TextBox on my form. The first button gets me an ILoader (below code), and the second button loads up a file viewer (ILoader, below code), whose file name is what is entered into the textbox on the winform.
Without An IOC Container I would do the following (let's just assume its put in the click event)
Button 1 Click Event :
ISplitText MyStringFunc = new WhateverImplementsIt();
Button 2 (gets the file reader based on textbox input)
ILoader MyLoader = new FileReaderImplementation(TextBox1.Text);
Using LightInject, I'm surely compelled to do the following:
Button1 Click:
ISplitText Splitter = Container.GetInstance<ISplitText>();
Button 2 Click
var LoaderFunc = Container.GetInstance<Func<string, ILoader>>();
ILoader l2 = LoaderFunc(TextBox1.Text);
Am I Incorrect? In A large project I would have Container.GetInstance, peppered all over the place, in the main form file and elsewhere surely, so how can i only reference the container in ONLY 1 spot, in the form of bootstrap, am i missing a magic piece of the puzzle?
In all the sample apps I have seen it's all done in one simple console app, in the Main function. All these apps follow the format of:
Container = new Container();
Container.Register<IFoo,Foo>();
Container.Register<IBar,Bar();
var Resolved = Container.GetInstance<IFoo>();
Well, I understand all that, and it's extremely simple. It's once you start adding a bit of complexity to the app itself, I'm lost as to how to get the instances without making the Container itself public, or static, or accessible in some way,shape or form and then calling Container.GetInstance in a million places (which apparently, is a big no no). PLEASE HELP!
Cheers,
Chud
PS - I am not concerned about "abstracting the container" itself. so would prefer to only focus on increasing my understanding of the above.
public class BootStrapIOC
{
public ServiceContainer Container;
public BootStrapIOC(ServiceContainer container)
{
Container = container;
}
public void Start()
{
Container.Register<ISplitText, StringUtil>();
Container.Register<string, ILoader>((factory, value) => new FileViewByFileName(value));
}
}
//HUH? How can i NOT use the container??, in this case in the button_click
ILoader Loader = Container.GetInstance<Func<string, ILoader>>();
ILoader l2 = Loader(TextBox1.Text);
ISplitText Splitter = Container.GetInstance<ISplitText>();
EDIT #1
OK, so, after re-reading the comments and looking at a few more examples on the interweb, I think I may finally understand it. The issue was (I think) is that i wasn't thinking "higher level" enough. I was trying to resolve my dependancies in my winforms application, AFTER the form had already been constructed,and in the form itself. When in reality, it's too late by then. I wasn't viewing the "form itself" as just another object, which needed it's dependencies injected into it.
So I bootstrap now in my Program.cs:
static class Program
{
private static ServiceContainer Container;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Container = new ServiceContainer();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
BootStrapIOC Strap = new BootStrapIOC(Container);
Strap.Start();
//This magic line resolves EVERYTHING for me required by the Form
var form = Container.GetInstance<Form1>();
Application.Run(form);
//Application.Run(new Form1());
}
}
My question now is, Is my line of thinking now correct in terms of winforms. It seems to make more sense, changing my approach to "higher up" the chain and resolving from Program.cs??
Secondly, And I'm not sure if this calls for a new question altogether, please advise as I am an SO noob.
How would I setup a factory to return the correct instance of an object? One of the original comments indicated that that would be a usage in this scenario. Let's use a contrived example.
Where I needed an object, but don't know which object until run time/user input.
My Idea:
BootStrap
Container.Register();
Factory Interface and Implementation:
Let's put some optional parameters in also, as I want to know if this is the correct/best way to do it?
public interface IFileViewerFactory
{
ILoader GetFileViewer(string FileName, string Directory = null, bool CreatingDirectory = false);
}
public class FileViewerFactory:IFileViewerFactory
{
public FileViewerFactory() { }
public ILoader GetFileViewer(string FileName, string Directory = null, bool CreatingDirectory = false)
{
if (CreatingDirectory == false)
{
if (Directory == null)
return new FileViewByFileName(FileName);
else
return new FileViewByDirectoryName(Directory, FileName);
}
else
return new FileViewByDirectoryNameCreateDirectoryOptional(Directory, FileName, CreatingDirectory);
}
}
Form:
public IFileViewerFactory FileViewerFactory { get; set; }
Button Click:
ILoader FileLoader = FileViewerFactory.GetFileViewer(TxtBoxFileName.Text);
Or:
ILoader FileLoader = FileViewerFacotry.GetFileViewer(TxtBoxFileName.Text,TxtBoxDirectory.Text);
So to finish off, my questions are:
Is my new way of "higher level" thinking, and bootstrapping from Program.cs now correct
How Can I handle optional parameters in LightInject
Is How I have setup my factory the correct way to do it?
Let's forget about the Fugliness of the factory and just try to work on the mechanics of the questions :)
I know it's a bit late to answer a question that is over a year old but let me try.
The issue here is that you don't want your container to go out anywhere else than your Composition Root. In a complex solution consisting of mutliple assembiles, this means the container itself is only referenced by the topmost assembly (where the Composition Root is).
But the application stack is usually complex, you possibly have multiple assembiles and still, your depencencies should be resolves across the application.
Historically, one of the possible approaches was the Service Locator pattern. The locator goes down to the very bottom of the stack and from there, it offers a service that resolves dependencies. Thus, it's available anywhere up the stack.
This approach has two drawbacks, first is that your container is referenced at the very bottom of the stack and even if you circuvment this you still have your locator referenced everywhere. The latter could be painful in a large app as you possibly have some standalone assembiles that you don't want to be forced to reference your locator (or anything else).
The ultimate solution is called the Local Factory (aka Dependency Resolver) and it takes care of creating just few of its dependand services. The trick is then to have multiple local factories across your app.
A typical setup is like this. Suppose there's an assembly, call it A, that the client will use to obtain an instance of IServiceA. The assembly contains only the two:
interface (obligation) of the service - IServiceA
the local factory clients will use to obtain instances of the service
And that's all, no other references, no containers. There's even no implementation at this point yet. The trick here is to make the factory open for the actual provider - in a sense that the factory doesn't even yet know how to create instances - it's the Composition Root that will tell it.
// Assembly A
public interface IServiceA
{
...
}
public class ServiceAFactory
{
private static Func<IServiceA> _provider;
public static void SetProvider( Func<IServiceA> provider )
{
_provider = provider;
}
public IServiceA Create()
{
return _provider();
}
}
the provider here has a functional contract but it could also be expressed as an interface
And that's all, although there's no implementation in the factory at the moment, the client code is suddenly very stable:
// client code to obtain IServiceA
var serviceA = new ServiceAFactory().Create();
Note again how self-contained this assembly A is. It has no other references, still, it offers a clean way to obtain instances of your service. Other assemblies can reference this assembly with no other additional references.
Then comes the Composition Root.
At the very top of your stack, your main assembly references the assembly A and some other assembly, let's call it AImpl that contains a possible implementation of the service interface.
technically the implementation of the service could be in the very same assembly the interface is but it only makes things easier
The Composition Root creates the provider of the factory by delegating a factory method down the stack, to the assembly A
// Composition Root in the top level module
// Both assemblies
// * A that contains IServiceA
// * AImpl that contains an implementation, ServiceAImpl
// are referenced here
public void CompositionRoot()
{
ServiceAFactory.SetProvider( () =>
{
return new ServiceAImpl();
} );
}
From now on, the provider is set up and all the client code down the stack that uses the factory, can succesfully obtain instances.
The Composition Root provides all other implementations of other local factories, as well. There are multiple setups then in the Composition Root:
SomeLocalFactoryFromAssemblyA.SetProvider( ... );
AnotherLocalFactoryFromAssemblyB.SetProvider( .... );
...
Where is your container then?
Well, the container is just one possible implementation of the provider. It only helps rather than spoils. Note however that you don't even have to use it, it's a choice rather than obligation.
public void CompositionRoot()
{
var container = new MyFavouriteContainer();
container.Register<IServiceA, ServiceAImpl>(); // create my registrations
ServiceAFactory.SetProvider( () =>
{
// this advanced provider uses the container
// this means the implementation, the ServiceAImpl,
// can have possible further dependencies that will be
// resolved by the container
container.Resolve<IServiceA>();
} );
}
This is the most clean setup I am aware of. It has all desired features:
it separates concerns in a clean way
the client doesn't really need any other dependencies than the service contract and the factory
the client doesn't even know there is or will be a container, in fact the client doesn't care
in a test environment, providers can easily be setup without any container, to provide static mocks of your services
the Composition Root is a real composer here - it's the only place in your code where the three: interfaces, implementations and the container, meet together

Creating Instance of a Class using reflection,whose parameters are injected by autofac [duplicate]

I'm trying to figure out how to resolve a instance somewhere in the code.
At the application startup I registered a type
static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<Foo>().As<IFoo>();
}
Now, how can I resolve an instance somewhere in the code ?
In StructureMAP there is a static object ObjectFactory.GetInstance<IFoo>()
Read up on Getting Started. It should get you started.
First off, what you are looking for is the container. Build it from the ContainerBuilder like in this simple WinForms app:
static void Main()
{
using (var container = builder.Build())
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var mainForm = container.Resolve<MainForm>();
Application.Run(mainForm)
}
}
The general idea is that you only have to resolve the first or topmost instance. The container will handle creating all other instances based on dependency injection through constructor parameters.
If the DI pattern is followed throughout your application you should only have to touch the container once at startup.
How you resolve the topmost instance depends largely on what type of application you are building. If its a web app, the ASP.Net integration and MVC integration will take care of it for you. (After all, the topmost instance in ASP.Net is the Application which is out of our control).
On the other hand, if its a console app or WinForms app you would resolve the first instance manually in Main, like my sample above.

How to Access ninject .Net Container across Application

I am trying to implement a simple application with the MVVM pattern using Dependency Injection With ninject.
The recommended way of using DI is to resolve all dependencies at just one point:
App()
{
kernel = new StandardKernel();
kernel.Bind<IService>().To<DefaultService>();
kernel.Bind<IMainWindow>().To<MainWindow>();
// Register all other dependencies here
// resolve all dependencies.
MainWindow mw = kernel.Get<IMainWindow>();
}
This is a very ideal scenario where all dependencies get resolved by just one call to the kernel and the kernel is not needed any more in the application.
However the problem is that there are "Views" in my application that need to be resolved e.g in the MainViewModel by just knowing the type of some specific UserControl that is only known at runtime.
The easiest way and at the same time worse (not recommended) is to pass the container as injected parameter in the constructor and then simply call:
void resolveByType(Type viewType)
{
// Container was injected in this class (Dirty!!!).
Container.Get(viewType)
}
This works fine but I am wondering if there is a better way to achieve the same behaviour?

Correctly use Dependency Injection pattern [duplicate]

I'm currently working on a WinForms system (I know) where there's a lot of Constructor Injection when creating forms, but if those forms/views need to open another form, I find the DI container has been injected too so that we can locate the implementation of the desired view interface at runtime. e.g.
public partial class MyView : Form, IMyView
{
private readonly IDIContainer _container;
public MyView(IDIContainer container)
{
InitializeComponent();
_container = container;
}
public OpenDialogClick(object sender, EventArgs e)
{
var dialog = container.Resolve<IDialogView>();
dialog.ShowDialog(this);
}
}
I'm aware that this is basically using the container as a service locator. I've been repeatedly told that this is considered an anti-pattern so I'd like to avoid this usage.
I could probably inject the view as part of the constructor like this :
public partial class MyView : Form, IMyView
{
private readonly IDialogView _dialog;
public MyView(IDialogView dialog)
{
InitializeComponent();
_dialog = dialog;
}
public OpenDialogClick(object sender, EventArgs e)
{
dialog.ShowDialog(this);
}
}
But what if the dialog view is quite expensive to instantiate?
It's been suggested that we create some kind of form factory which internally uses the DI container, but to me this seems like simply creating a wrapper around another service locator.
I know that at some point, something has to know how to create an IDialogView, so I'm thinking that either it's resolved when the composite root is created (probably not ideal if there are many forms and some or all are expensive to create), or the composite root itself has a way to resolve the dependency. In which case the composite root has to have a service-locator-like dependency? But then how would child forms create dialogs like this? Would they call up to the composite via, say, events, to open dialogs like this?
One particular problem I keep running up against is that the container is almost impossible to mock easily. This is partly what keeps me thinking about the form factory idea, even though it would just be a wrapper around the container. Is that a sensible reason?
Have I thought myself into a knot? Is there a simple way through this? Or do I just cut the knot and find something that works for me?
Or do I just cut the knot and find something that works for me?
Factory class:
public interface IDialogFactory {
IDialogView CreateNew();
}
// Implementation
sealed class DialogFactory: IDialogFactory {
public IDialogView CreateNew() {
return new DialogImpl();
}
}
// or singleton...
sealed class SingleDialogFactory: IDialogFactory {
private IDialogView dialog;
public IDialogView CreateNew() {
if (dialog == null) {
dialog = new DialogImpl();
}
return dialog;
}
}
Your code:
public partial class MyView : Form, IMyView {
private readonly IDialogFactory factory;
public MyView(IDialogFactory factory) {
InitializeComponent();
//assert(factory != null);
this.factory = factory;
}
public OpenDialogClick(object sender, EventArgs e) {
using (var dialog = this.factory.CreateNew()) {
dialog.ShowDialog(this);
}
}
}
Registration with SimpleInjector
container.RegisterSingle<IDialogFactory, DialogFactory>();
or using singleton version
container.RegisterSingle<IDialogFactory, SingleDialogFactory>();
container.RegisterSingle<IMyView, MyView>();
A local factory, satisfied with an implementation that uses the container and set up in the composition root is not a service locator, it is a dependency resolver.
The difference is as follows: the locator is defined and satisfied somewhere near the definition of the container. In a separate project, to use the locator, you need an external reference to the container infrastructure. This causes the project to rely on external dependency (the locator).
On the other hand, the dependency resolver is local to the project. It is used to satisfy dependencies in its close neighbourhood but it doesn't depend on anything external.
The composition root should not be used to resolve actual specific dependencies such as the one you are concerned about. Instead, the compositon root should set up implementations of all these local dependency resolvers that are used throughout the application. The more local resolver, the better - the MVC's constructor factory is a good example. On the other hand, WebAPI's resolver handles quite few of different services and it is still a good resolver - it is local in the webapi infrastructure, it doesn't depend on anything (rather - other webapi services depend on it) and it can be implemented in any possible way and set up in the Composition Root.
Some time ago I wrote a blog entry about it
http://www.wiktorzychla.com/2012/12/di-factories-and-composition-root.html
There you will find your issue discussed and an example of how you set up a factory aka resolver.
You definitely do not want to pass your DI container around your application. Your DI container should only be part of your Composition Root. You could, however, have a factory that uses the DI container within the Composition Root. So if Program.cs is where you are wiring everything up, you could simply define that factory class there.
WinForms was not designed with DI in mind; forms are generated and therefore need default constructors. This may or may not be an issue depending on which DI container you use.
I think in this case, the pain of using constructor injection in WinForms is greater than the pain of any pitfalls you may encounter while using a service locator. There's no shame in declaring a static method in your Composition Root (Program.cs) that wraps a call to your DI container to resolve your references.
I know this problem very well. Everything I learned about solution to this (and I learned A LOT) is more or less camouflaging service locator.

How solve circular reference in Caliburn.Micro

I am working with Caliburn.Micro v2.0.1 on a Windows 8.1 Unversal (WinRT) project.
I followed the Caliburn.Micro Working with WinRT example.
My code looks as follows:
App.xaml.cs
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
Initialize();
DisplayRootViewFor<LoginViewModel>();
}
protected override void PrepareViewFirst(Frame rootFrame)
{
_container.RegisterNavigationService(rootFrame);
}
LoginViewModel.cs
public LoginViewModel(INavigationService navigationService, ...)
{
...
}
The issue
The OnLaunched is called first.
Initialize() Configures the WinRT container.
The DisplayRootViewFor<LoginViewModel> invokes an instance of the LoginViewModel and results in a Null exception because NavigationService has not yet been registered by PrepareViewFirst(Frame)
PrepareViewFirst(Frame) is not yet called, having a dependency on the RootFrame that should be configured by OnLaunched
Thus LoginViewModel is dependent on RegisterNavigationService and RegisterNavigationService is dependent on DisplayRootViewFor<LoginViewModel>() which is dependent on LoginViewModel
Is there any way to overcome this circular reference issue?
Register your services in the container before resolving the Views - this way all dependencies are available in the particular Dependency Injection container and you can use ServiceLocator to find them.
Typically I've always done this in the OnStartup() method of App.xaml.cs.
You should register/configure your container at the composition root, the earliest access point of your application.
This point depends on what kind of Application you have:
ASP.NET MVC: Global.asax.cs
Console Application: the Main Method
WPF: Application.OnStartup
WinPhone 7: See https://stackoverflow.com/a/7310492/455493
etc.
Check the Windows 7 lifecycle on http://msdn.microsoft.com/en-us/magazine/hh148153.aspx

Categories

Resources