I've got a question about the cleanest way for constructing new instances of some abstraction in a factory using Dependency Injection. The thing is that I use some presenter which opens it's views multiple times, but when we only "close" some view, it's being disposed, and to open the view again I need to get a new View instance once again and then I can open it.
For now the "factory" looks like this:
class ViewConstructor<TView> :IViewConstructor<TView>
where TView : class, IView
{
private readonly IIocContainer _iocContainer;
public ViewConstructor(IIocContainer iocContainer)
{
_iocContainer = iocContainer;
}
public TView Construct()
{
return _iocContainer.GetInstance<TView>();
}
}
The thing is, that I know that using IocContainer anywhere but not in the composition root it a bad thing. So I'm guessing if there's some "clean" way to implement this. To sum up, i want to be able to get MULTIPLE instances of the IView from the factory.
I found an answer in the post: https://stackoverflow.com/a/17436520/4777147
It seems, that solution may be to spawn a view using "new" in the factory.
Unfortunately, in order to use generic factory, every view has to have default constructor. Otherwise you'll need specialized factories for every view.
Related
I delegate creation(showing) of my Windows to my WindowFactory, that attaches a ViewModel to the View and shows the window. It is injected into my MainViewModel Constructor parameters.
The factory itself is very simple:
public class ProductionWindowFactory : IWindowFactory
{
public void CreateNewWindow()
{
PhoneWindow window = new PhoneWindow();
{
window.DataContext = new phoneWindowViewModel();
}
window.Show();
}
}
Now, I'm aiming at implementing more functionality of my new windows, that will happen on certain button clicks IN that new window.
As I am fairly new to Factories in general, I'm struggling to grasp a certain concept:
Example:
We have a ViewA that has a ViewModelA attached to it.
That view has a button with a command attached, that tells our WindowFactory to show a new ViewB.
ViewB has a ViewModelB and a close button, that tells it to close ViewB.
Now, since we shouldn't reference our ViewB in our ViewModelB, we have to somehow let it know which view it should close.
I have come up with possible ideas / solutions, but I would really
appreciate you letting me know which one follows the MVVM and Factory
pattern "the most", and which one is usually used in such situations.
Make our ViewModelB take an instance of windowFactory that created ViewB as a parameter on initialization, and build a method in the Factory that closes ViewB and is executed through button click -> command.
Create an IWindowManager? that inherits from IWindowFactory and build a WindowManager class, that extends the capabilities of our WindowFactory, and push it in ViewModel constructors as described above.
Any other correct solution, that I am completely unaware of?
Please bear in mind, that the above is just an example. Ideally, I'd like to implement more of advanced functionality to my windows, and have an ability to create & manage multiple different ones using that one factory.
I have not attached much code, since I'm still at the stage of learning and deciding which solution should I go with.
EDIT - REGARDING POSSIBLE DUPLICATE:
My question differs from the proposed duplicate, as the other one is simply about managing of closing windows - My question is about doing that as well, but following a FactoryPattern.
I have specified very clear guidelines in what I am trying to achieve and in what ways, that are completely different from the question linked.
First of all, the answer is none. The job of a factory is to create new objects, think of it as an elaborate new operator. Also, the idea of following a pattern "the most" is problematic in and of itself. You employ patterns because they help you achieve certain goals, e.g. you employ mvvm to evade coded-ui tests as much as possible, because they are fragile, normally.
That being said, what to do with its view is completely up to the view's view model.
Example: if one view model needs to close its own window, do it with a command as illustrated in the comment. If a view has a close all-button, its view model will have a dependency on some kind of window registry that can enumerate all open windows for the close all-command to close.
When looking at your view model, try to come up with an idea of what services it needs from the rest of the application, and inject those dependencies as interfaces. When implementing the interfaces, most likely there will be classes that implement more than one, e.g. WindowManager might implement IWindowFactory and IWindowRegistry thus making it very easy to put all newly created windows into the list of open windows. The window will have a dependency on the IWindowRegistry, too, most likely, to unregister itself when it gets closed.
The duplicate was not far off. Here is a simple adaptation of the scenario in OP
interface IView {
void Close();
}
class ViewAdapter : IView {
readonly Window view;
public ViewAdapter(Window view){
this.view = view;
}
public void Close() {
view.Close();
}
}
public class ProductionWindowFactory : IWindowFactory {
public void CreateNewWindow() {
var view = new PhoneWindow();
var viewAdapter = new ViewAdapter(view)
var viewModel = new phoneWindowViewModel(viewAdapter);
//Bind
view.DataContext = viewModel;
view.Show();
}
}
If the view model wants to instruct that the view be closed it can ask the injected contract to do so.
For a project I am working on, I decided to adopt the MVVM pattern.
My viewmodel needs to launch many different dialogs, which do more than just simply show OK or Cancel buttons. Most dialogs have a listview to select an item from.
To keep the viewmodel "lookless" I am injecting the different dialogs as interfaces in the viewmodel constructor.
public ContractsData(IWindow ProjectSelector, IWindow ContractSelector, IWindow DebtorSelector)
{
//.....
//.....
m_ProjectSelector = ProjectSelector;
m_ContractSelector = ContractSelector;
m_DebtorSelector = DebtorSelector;
}
With IWindow being:
public interface IWindow
{
void Close();
bool? ShowDialog();
void SetOwner(object window);
bool? DialogResult { get; set; }
object DataContext { get; set; }
}
However nice it is to be able to separate data from views from a testing point of view, all possibly needed dialog windows have to be present and fully constructed upon construction of the viewmodel, which goes against one of my principles, that of "lazy initialisation": only construct an object when you need it.
As my viewmodel grows, it will possibly need a whole bunch of dialogs, which will all be created up front and sleeping in memory until needed, which very well may never be.
I was thinking of replacing the actual dialogs with lightweight "Factory" objects, that construct the dialogs on request from the view, but I am looking for a better solution to solve the memory issues with dependency injection.
If you're using a dependency injection container, most of them will be having a feature to inject Lazy<T>. So instead of IWindow you could take dependency on Lazy<IWindow>. Without any special registrations they are clever to inject Lazy<T> for you.
If you're using poor man's injection, you could manually construct Lazy<IWindow> and inject it. Otherwise Abstract factory is another good option.
I am writing my first WPF application and I would like to ask you for help with a problem that I encountered.
I am trying to follow the MVVM pattern and I came to a point where I need to implement modal dialogs. I googled/read on the topic for some time and I was able to settle on a solution. However, when refactoring I encountered a dilemma that concerns using a DI (constructor injection) as a replacement of a service locator.
I am going to be referencing these: http://pastebin.com/S6xNjtWW.
I really like the approach of Roboblob:
First: He creates an abstraction of a modal dialog (interface). I named the interface IModalDialog and this is how it looks like:
public interface IModalDialog
{
bool? DialogResult { get; set; }
object DataContext { get; set; }
void Show();
bool? ShowDialog();
void Close();
event EventHandler Closed;
}
Second: An abstraction of modal dialog service:
public interface IModalDialogService
{
void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose) where TDialogViewModel : class;
void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel) where TDialogViewModel : class;
}
Third: The concrete implementation of IModalDialogService:
public class ModalDialogService : IModalDialogService
{
public void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose) where TDialogViewModel : class
{
// set datacontext
if (viewModel != null)
{
view.DataContext = viewModel;
}
((System.Windows.Window)view).Owner = System.Windows.Application.Current.MainWindow;
// register
if (onDialogClose != null)
{
view.Closed += (sender, e) => onDialogClose(viewModel);
}
view.ShowDialog();
}
public void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel) where TDialogViewModel : class
{
this.ShowDialog(view, viewModel, null);
}
Fourth: There are more implementations of IModalDialog. Each is a Window-derived class that implements IModalDialog.
Before I ask the question (describe the problem), I need to explain this beforehand:
Let's say that I have some more services, like for example IMessageBoxService.
Then I need to declare these dependencies in the constructor of MainWindowViewModel:
public MainWindowViewModel(IModalDialogService a,
IMessageBoxService b,
...)
so that I can inject them (either by hand or using IOC container like Unity, etc.).
In order to be able to use the modal dialog service there is one missing piece of puzzle - the ability to resolve a concrete implementation of IModalDialog based on some key.
Roboblob in his article solves this last piece of puzzle using a ServiceLocator pattern:
public class Bootstrapper
{
public static void InitializeIoc()
{
SimpleServiceLocator.SetServiceLocatorProvider(new UnityServiceLocator());
SimpleServiceLocator.Instance.Register<IModalDialogService, ModalDialogService>();
SimpleServiceLocator.Instance.Register<IMessageBoxService, MessageBoxService>();
...
SimpleServiceLocator.Instance.Register<IModalWindow, EditUserModalDialogView>(Constants.EditUserModalDialog);
}
}
so he inside his MainWindowViewModel simply calls the static classes Get and resolves a concrete implementation of IModalDialog window based on a key.
Even Josh Smith uses a similar approach in his article but in comments he says that (DI - constructor injection) is a valid option.
The referenced StackOverflow answer also describes a similar WindowViewLoaderService that could be modified and use.
So the question is - what would be the best way to replace the ServiceLocator (which resolves the concrete implementations of IModalDialog) with a dependency injection?
My train of thoughts was:
One possibility is (due to the project not being very big/developed by me only) to just create a new service (e.g. called IModalDialogResolver) that would create and return new instances of concrete implementations of IModalDialog. Have all the services injected by hand.
Then I thought about an IOC container (Unity). I have no experience with it. I thought that maybe I don't have to write the IModalDialogResolver as I could register the different implementations of IModalDialog with Unity container => but then how do I use the container inside MainWindowViewModel? I cannot pass the reference to the constructor as that would be a step back to ServiceLocation.
So then I thought that maybe I can use one unity container in the bootstrapper to resolve all the services and use another one internally inside the IModalDialogResolver. But I don't know whether this is a good idea regarding the recommended usage of Unity. I really know too little to judge this. But something tells me that this is not a good idea as it creates a hidden dependency on the container + if the container is a singleton that would be equivalent to just passing the reference into the constructor.
To maybe better explain the mental block that I have: I would like to use an IOC container (e.g. Unity) to have the interfaces constructed and injected by it. But then I cannot just put IModalDialog as a parameter inside a constructor. So probably I really need to wrap this inside a service and implement myself - but then (provided that Unity can do this out of the box) it doesn't make sense to have Unity there in the first place if i cannot use it.
I know one of the alternatives is to put this one service into a base class, but for the sake of argument, let's not consider this. I really would like to learn about the right way to have this solved using dependency injection.
It's perfectly valid and expected for you to access the IoC container within your composition root.
In fact this should be the only location where you container is accessed.
In the example you've given, that's all that is happening - the concrete implementations are being registered in the container within the composition root.
So to answer your question, you don't need to replace the use of the service locator pattern here, as it's just a mechanism for registering the types in the composition root, which is perfectly valid.
If you wish to instantiate the modal dialog service based on some run time conditions, then you should inject a model dialog service factory instead (again an abstraction with an implementation registered in your container), and then the factory would have a method to create the model dialog service and this factory method would take the run time parameters required.
Your factory could then new up the appropriate model dialog service appropriately based on the run time parameters. Alternatively, it could also resolve the appropriate model dialog service from the container, which would obviously require the factory to have a reference to the container.
Most containers support automated factory types, so that you only need to define the interface for the factory, and the container will automatically implement the factory using conventions. Castle.Windsor for example has the Typed Factory Facility and Unity has some equivalents.
I'm using Caliburn and C#, but I feel like this is a generic MVVM/DI question.
Let's say I have a view model, NoteViewModel, that is passed a model object called Note.
Here is some code:
class NoteViewModel : PropertyChangedBase
{
private readonly Note _note;
public NoteViewModel(Note note)
{
_note = note;
}
public string Title
{
get { return _note.Title; }
set { _note.Title = value; NotifyOfPropertyChange(() => Title); }
}
}
Right now this object is created by calling new() and passing a model object.
Well, that works great, but now I need to add a method that requires an imported class from my DI container.
So do I merely call ServiceLocator.Current.GetInstance() to get it? Or should I design this view model to be created via the DI container and somehow setup a way to pass a Note object?
What is the proper way to design this view model? Basically a "PerInstance" view model that requires a model object for it's use. Does Caliburn have a built-in way to do this?
Caliburn has an interface (IHaveSubject and its typed version IHaveSubject) addressing this kind of scenario: basically it allows a mean to configure the ViewModel with a "subject" after its instantiation, tipically through the container:
class NoteViewModel : PropertyChangedBase, IHasSubject<Note> {
...
}
myNoteViewModel = ... //obtain an instance
myNoteViewModel.WithSubject(new Note());
This solution also integrates well with ISubjectSpecification / Conductor
infrastructure.
Even though post-construction initialization is a simple and effective solution, you may not want (from a pure design perspective) to renounce to an explicit constructor parameter to enforce the need for a Note to istantiate the ViewModel.
In this case I think you have to leverage peculiar features of your DI container, because you may have some parameters of the constructor representing a "real" input parameter, while other may be service dependencies.
Castle Windsor, for example, has a nice feature allowing you to quickly build an explicit (typed) factory for your ViewModel; the factory method will only allow to set the "real" parameters, while all dependencies are managed by the container (see this post for an extensive description of this Windsor feature: http://kozmic.pl/archive/2009/12/24/castle-typed-factory-facility-reborn.aspx)
Can you solve it using hierarchical view models?
To me it becomes more and more clear that I need one ViewModel per View and one ViewModel per model item or collection when building larger application.
That way we can build up ViewModels hierarchically, matching the XAML hierarchy.
The required objects can be defined or injected at the top level by app's main view model then. The nested view models can then access anything the way you design it to make things reachable by them.
About Caliburn, I don't know any specific things about that framework, sorry.
I'm using the ServiceLocator also. And I also "feel dirty" in doing this. But I have resolved to use the YAGNI principle and keep this pattern until I find a compelling payback to the complexity of adding 5 IServices into my constructors, passing them up via 3-4 layers of inheritance to the base classes in which they are needed, and creating everything via the container. Of course my app is evolving, and YAGNI doesn't always last...
I've just refactored out a new domain class from a presenter class but I can't figure out where to instantiate it.
This is part of a larger ongoing refactoring effort with a poorly maintained legacy project.
The Presenter is currently being created by the view's OnLoad event and the view is passed as a parameter in the constructor. All public methods in the presenter are parameterless and return void. They communicate with the view using public properties of the view.
The view, being essentially a humble form depends entirely on the presenter for everything.
This is the typical Passive View pattern and I'd like to continue to adhere to it. Which brings me to my dilemma. I need to create an instance of my new domain object for the presenter to use.
If I pass it through the constructor then the view has to create it and gains an unnecessary dependency.
If I create it anywhere within the presenter, I can't replace it with a mock object in my unit tests.
If I make it a public property of the presenter then I introduce a creation order dependency on the presenter methods where it is used and I still haven't solved what external class gets responsibility for creating it.
I am not currently using any dependency injection frameworks. While I'm interested it using one in the future the source code is still much to fragile to introduce a third party framework into the mix.
I'm open to any suggestions.
I have it already done !!!
Have a look here in my repository. My choice here is to use constructor ... satisfying the greediest I'm sure that presenter is Up. In your case you can provide from view specific impl for dependencies.
have fun :)
I found a much simpler solution. Here's an example of my original class:
public Presenter(IView view)
{
this.View = view;
}
I wanted to pass my new dependency as a constructor argument but didn't want to add this dependency to my view as well. Constructor chaining to the rescue!
public Presenter(IView view):this(view, new Dependency()){}
public Presenter(IView view, IDependency dependency)
{
this.View = view;
this.Dependency = dependency;
}
Now the production code continues to use the original interface while the unit tests use the new one passing in mocks for both the view and dependency. If the number of dependencies continues to grow some refactoring will be needed but for the immediate future this is an ideal solution.
I'd go for a repository or a factory for now. It would be testable immediately. In the future, you can replace its implementation to go to a DI library.
public class DomainObjectsRepository
{
/// <summary>
/// can not be instantiated, use <see cref="Instance"/> instead.
/// </summary>
protected DomainObjectsRepository()
{
}
static DomainObjectsRepository()
{
Instance = new DomainObjectsRepository();
}
public static DomainObjectsRepository Instance { get; set; }
public virtual ICustomerDao GetCustomerDao()
{
return new CustomerDao();
}
}
public class DomainObjectsRepositoryMock : DomainObjectsRepository
{
public override ICustomerDao GetCustomerDao()
{
return new CustomerDaoMock();
}
}