I know that in MVVM pattern (or possibly in any design pattern of this kind) we should keep our layers decoupled. From my understanding it also means, that I should keep my ViewModels separate. I'm having a bit trouble following this rule.
Say - I have a ConversationViewModel and a MessageViewModel - the former needs to create instances of the later. When ConversationViewModel gets notification about incoming message it spawns a new MessageViewModel instance and fills it with data.
The question is - if I create new MessageViewModel instances explicitly in the ConversationViewModel won't it make my app a bit harder to test? I mean - one unit of code is the ConversationViewModel and other is the MessageViewModel - I'd like to test both separate, so when somebody breaks something in the later, test for the former won't be affected. How do I achieve it?
I'm using MVVMLight, so I thought I would register MessageViewModel as an implementation of some interface, and then create a class like MockMessageViewModel implementing the same interface, but used only in tests. Then in the ConversationViewModel I'd ask the IOC container to just give me the registered implementation. Is it a good approach, or am I overreacting? Example code:
public class ViewModelLocator {
public ViewModelLocator() {
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (//in test) {
SimpleIoc.Default.Register<IMessageViewModel, MockMessageViewModel>();
}
else {
SimpleIoc.Default.Register<IMessageViewModel, MessageViewModel>();
}
}
public class ConversationViewModel : ViewModelBase {
public void MessageReceived(string data) {
//I'm thinking about doing this:
var vm = SimpleIoc.Default.GetInstance<IMessageViewModel>();
// instead of doing this
var vm = new MessageViewModel();
//do stuff with vm
}
}
Whether to use interface bases approach to separate the view models from each other is the design decision based on complexity of your application.
If you want to dynamically create instance of IMessageViewModel inside IConvesationViewModel; I would recommend instead of referring to IoC container in your ViewModel class inject a factory for creating IMessageViewModel in the ConversationViewModel constructor. Later you can use this factory to create instances of IMessageViewModel. A simple implementation of factory could be Func delegate.
public class ConversationViewModel
{
private Func<IMessageViewModel> _messageViewModelFactory;
public ConversationViewModel(Func<IMessageViewModel> messageViewModelFactory)
{
_messageViewModelFactory = messageViewModelFactory;
}
public void MessageReceived(string data) {
var messageViewModel = _messageViewModelFactory();
}
}
This way you are exposing dependencies of your ConversationViewModel class through the constrctor instead of hiding them inside the class implementation.
The IoC containers like Autofac provide way to inject Func in the constructor when you create object of ConversationViewModel using it.
I believe a better way to do that is by using interfaces. You can have both your real and mock ViewModels implement the same interface and use that interface everywhere where you would use a ViewModel class.
If it was me and I may not have all the information about your application but I would have a single ViewModel IConversationViewModel. And in the IConversationViewModel I would have a collection of IMessageModel instances. I would not go nesting ViewModels.
What you can do is create the MessageViewModel immediately in ViewModelLocator and register for receiving messages in MessageViewModel using the MVVMLight MessengerInstance in its constructor. Something like this:
public class ViewModelLocator
{
public class ViewModelLocator()
{
//creates instance immediately
SimpleIoc.Default.Register<MessageViewModel>(true);
}
}
public class MessageViewModel:ViewModelBase
{
public MessageViewModel()
{
MessengerInstance.Register<string>(this,DoSomething);
}
public void DoSomething(string data)
{
//do stuff
}
}
public class ConversationViewModel:ViewModelBase
{
public void MessageReceived(string data)
{
MessengerInstance.Send<string>(data);//this will trigger DoSomething in MessageViewModel
}
}
Related
I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)
Related to this other question: How to inject an action into a command using Ninject?
Based on the comments on the above-referenced question, I take it that I would just need to create some command classes and inject them in my view model so that the view's controls just need to bind to them. I conceptually agree and understand the benefits. Besides, I wish to be as clean as possible using Ninject, DI and Constructor Injection.
Following these important rules, here's what I've come with so far.
CreateCategoryCommand
public class CreateCategoryCommand : ICommand {
public CreateCategoryCommand(CreateCategoryView view) {
if(view == null) throw new ArgumentNullException("view");
this.view = view;
}
public bool CanExecute(object parameter) { return true; }
public event EventHandler CanExecuteChanged;
public void Execute(object parameter) { view.Show(); }
private readonly CreateCategoryView view;
}
CategoriesManagementViewModel
public class CategoriesManagementViewModel {
public CategoriesManagementViewModel(ICommand createCommand) {
if (createCommand == null) throw new ArgumentNullException("createCommand");
this.createCommand = createCommand;
}
public ICommand CreateCommand { get { return createCommand; } }
private readonly ICommand createCommand;
}
So now when the CategoriesManagementView is initialized, it is constructor-injected with the CategoriesManagementViewModel, which in turn is constructor-injected with the CreateCategoryCommand, which in turn is constructor-injected with the CreateCategoryView, so no redundant dependency, neither any cycle-dependency.
Now, when I the CategoriesManagementView.CreateButton, it shall trigger the bound CategoriesManagementViewModel.CreateCommand, which will show the CreateCategoryView to the user, and this view shall have its own proper commands as well injected the same way.
Finally, this would render the RelayCommand class as useless...
Is that it?
First, I agree that RelayCommand and DelegateCommand and the like are ways of implementing commands that violate SOLID principles, so your solution here to replace them with a separate class is the correct one. Doing so also keeps your ViewModels much cleaner.
That said, you're violating MVVM pretty badly by having a class in your ViewModels layer (the CreateCategoryCommand) have knowledge of a concrete that is in your Views layer (CreateCategoryView). Nothing in your ViewModels layer should have a direct reference to anything in your Views layer.
Imagine it this way - you've separated your layers out into different dlls - Views.dll, ViewModels.dll, Models.dll, DataLayer.dll. If something in your ViewModels has a reference to a concrete in your Views, and obviously your Views will have a reference to ViewModels (as is necessary), then you have a circular reference problem.
The solution is to have your View object implement an interface (Interface Segregation Principle) like IDialog or IUiDisplay (choose the name depending on how abstract you want to be), and have your command have a dependency on that interface, NOT the direct concrete type, like so:
In Views:
public class CreateCategoryView : ..., IUiDisplay
{
...
}
In ViewModels:
public interface IUiDisplay
{
void Show();
}
public class CreateCategoryCommand : ICommand
{
public CreateCategoryCommand(IUiDisplay uiDisplay) {
if(display == null) throw new ArgumentNullException("uiDisplay");
this.display = uiDisplay;
}
private readonly IUiDisplay display;
...
}
Now, your Command no longer has a direct dependency on a concrete (so it is now mockable and testable!) from a higher layer. Now you can have your DI/IOC resolve the command dependency to the specific view class you want to inject. (I'd personally inject a view factory into the command instead, and only create the view lazily, but that's a different discussion).
One related note - if you implement commands by directly having them implement ICommand, then you're going to repeat yourself a lot (DRY). My suggestion is to create an abstract base class (CommandBase or something) that implements the requirements of ICommand. You'll find that all your commands that derive from it will only override Execute() and sometimes CanExecute(). This saves you from having to implement the event (and code to raise the event) in every command, and in many cases saves you from having to implement CanExecute since most commands just return true.
I have a ModuleLoader : NinjectModule which is where I bind everything.
Firstly I use
Bind<Form>().To<Main>();
to Bind a System.Windows.Forms.Form to my Main form.
Is this correct?
Secondly in the Program.cs I use this:
_mainKernel = new StandardKernel(new ModuleLoader());
var form = _mainKernel.Get<Main>();
Where _mainKernel is a ninject standard kernel.
Then I use Application.Run(form)
Is this correct?
I'm unsure as to what to bind together when it comes to Windows.Forms.
Thanks for any help.
You shouldn't really be binding to System.Windows.Forms.Form. Ninject is primarily meant for binding interfaces to concrete types so that you can pass around dependencies as interfaces and switch out the concrete implementation at runtime/during tests.
If you just want to use Ninject to create your Form in this way though, you'd simply use Bind<MyForm>().ToSelf() then do kernel.Get<MyForm>(). If you are requesting the concrete type directly though and it doesn't take any dependencies, there's not much point in using Ninject to initialise it.
In your situation, if your form implements an interface then you would do: Bind<IMainForm>().To<MainForm>() and request the interface type from Ninject. Usually your interface shouldn't be bound to the concept of a "form" though, it should be agnostic of the implementation (so later you could produce a CLI and website version and simply swap the Ninject bindings).
You could use the Model-View-Presenter design pattern (or a variant) to achieve this like:
public interface IUserView
{
string FirstName { get; }
string LastName { get; }
}
public class UserForm : IUserView, Form
{
//initialise all your Form controls here
public string FirstName
{
get { return this.txtFirstName.Text; }
}
public string LastName
{
get { return this.txtLastName.Text; }
}
}
public class UserController
{
private readonly IUserView view;
public UserController(IUserView view)
{
this.view = view;
}
public void DoSomething()
{
Console.WriteLine("{0} {1}", view.FirstName, view.LastName);
}
}
Bind<IUserView>().To<UserForm>();
Bind<UserController>().ToSelf();
//will inject a UserForm automatically, in the MVP pattern the view would inject itself though
UserController uc = kernel.Get<UserController>();
uc.DoSomething();
I'm trying to implement DI in a class, but I'm not sure that my design is appropriate.
The relevent code in the class I want to add DI to
class DoerValidation
{
public DoerValidation()
{
compileData();
}
private void compileData()
{
doersActive = Doer.GetActiveDoers();
//...
}
}
And in my Doer class
public partial class Doer
{
private static readonly DoerRepository repository = new DoerRepository();
public static IEnumerable<Doer> GetActiveDoers()
{
return repository.Doers.Where(c => c.Person.IsActive);
}
}
I just don't get how I could implement DI in this situation. Maybe the GetActiveDoers method is bad design? Where would you put this method otherwise?
Would it be a good practice to start adding new methods directly in the repository? Some people told me it should stay clean so it implements only this
public interface IDoerRepository
{
IQueryable<Doer> Doers { get; }
void SaveDoer(Doer doer);
void DeleteDoer(Doer doer);
}
It sounds like you need to inject the DoerRepository into DoerValidation basically - pass it into the constructor.
Both the GetActiveDoers and the static variable go against the principles of DI, IMO.
Static methods and properties are procedural in nature. If you expose your GetActiveDoers() method statically, there is no way to inject its functionality -- clients can only ignore it or use it inline wherever it's needed.
If you're committed to DI and to a static implementation, you need to write an instance wrapper for that static class and inject the instance wrapper.
I'm trying to remove a Service Locator from an abstract base class, but I'm not sure what to replace it with. Here is a psuedo-example of what I've got:
public abstract class MyController : Controller
{
protected IKernel kernel;
public MyController(IKernel kernel) { this.kernel = kernel); }
protected void DoActions(Type[] types)
{
MySpecialResolver resolver = new MySpecialResolver(kernel);
foreach(var type in types)
{
IMyServiceInterface instance = resolver.Get(type);
instance.DoAction();
}
}
}
The problem with this is that the instanciator of a derived class doesn't know what bindings the kernel must have in order to keep MySpecialResolver from throwing an exception.
This might be intrinsicly intractable because I don't know from here which types I'll have to resolve. The derived classes are responsible for creating the types parameter, but they aren't hardcoded anywhere. (The types are based on the presence of attributes deep within the derived class's composition hierarchy.)
I've trying to fix this with lazy loading delegates, but so far I haven't come up with a clean solution.
Update
There are really two issues here, one is that the IoC container is passed to the controller, acting as a service locator. This is easy to remove--you can move the location up or down the call stack using all sorts of techniques.
The second issue is the difficult one, how can you ensure that the controller has the necessary services when the requirements aren't exposed until runtime. It should have been obvious from the start: you can't! You will always be dependent upon either the state of the service locator or contents of a collection. In this particular case no amount of fiddling will ever resolve the problem described in this article with staticly typed dependencies. I think that what I'm going to end up doing is passing a Lazy array into the controller constructor and throwing an exception if a required dependency is missing.
I agree with #chrisichris and #Mark Seemann.
Ditch the kernel from the controller. I'd switch your resolver composition a little bit so that your controller can remove the dependency on the IoC container and allow the resolver to be the only item that worries about the IoC container.
Then I would let the resolver get passed into the constructor of the controller. This will allow your controller to be far more testable.
For example:
public interface IMyServiceResolver
{
List<IMyServiceInterface> Resolve(Type[] types);
}
public class NinjectMyServiceResolver : IMyServiceResolver
{
private IKernal container = null;
public NinjectMyServiceResolver(IKernal container)
{
this.container = container;
}
public List<IMyServiceInterface> Resolve(Type[] types)
{
List<IMyServiceInterface> services = new List<IMyServiceInterface>();
foreach(var type in types)
{
IMyServiceInterface instance = container.Get(type);
services.Add(instance);
}
return services;
}
}
public abstract class MyController : Controller
{
private IMyServiceResolver resolver = null;
public MyController(IMyServiceResolver resolver)
{
this.resolver = resolver;
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
Now your controller isn't coupled to a specific IoC container. Also your controller is much more testable since you can mock the resolvers and not require an IoC container at all for your tests.
Alternatively, if you don't get to control when a controller is instantiated, you can modify it slightly:
public abstract class MyController : Controller
{
private static IMyServiceResolver resolver = null;
public static InitializeResolver(IMyServiceResolver resolver)
{
MyController.resolver = resolver;
}
public MyController()
{
// Now we support a default constructor
// since maybe someone else is instantiating this type
// that we don't control.
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
You would then call this at your application start up to initialize the resolver:
MyController.InitializeResolver(new NinjectMyServiceResolver(kernal));
We did this to handle elements created in XAML who require dependencies resolved but we wanted to remove Service Locator like requests.
Please excuse any syntactical errors :)
I'm writing a blog post series on the topic of refactoring an MVVM application with Service Locator calls in the view models you might find interesting. Part 2 is coming soon :)
http://kellabyte.com/2011/07/24/refactoring-to-improve-maintainability-and-blendability-using-ioc-part-1-view-models/
Maybe you should just do away the Kernel, Types and MySpecialResolver and let the subclasses call DoActions with the IMyServiceInterface instances they need as argument directly. And let the subclasses decide how they get to these instances - they should know best (or in case they don't know which exactly the one who ever decides which instances of IMyServiceInterface are needed)
I would have liked to have a bit more information before posting this answer, but Kelly put me on the spot. :) Telling me to put my code where my mouth is, so to speak.
Like I said in my comment to Kelly, I disagree with moving the resolver/locator from a static implementation to an injected implementation. I agree with ChrisChris that the dependencies the derived type needs should be resolved in that class and not delegated to the base class.
That said, here is how I would remove the service location...
Create Command Interface
First of all I would create a command interface for the specific implementation. In this case the types sent with the DoActions method are generated from attributes, so I would create an IAttributeCommand. I am adding a Matches method to the command in order to declare the command for use by certain types.
public interface IAttributeCommand
{
bool Matches(Type type);
void Execute();
}
Add Command Implementations
To implement the interface, I pass in the specific dependencies I need to execute my command (to be resolved by my container). I add a predicate to my Matches method, and define my Execute behavior.
public class MyTypeAttributeCommand : IAttributeCommand
{
MyDependency dependency;
SomeOtherDependency otherDependency;
public MyTypeAttributeCommand (MyDependency dependency, ISomeOtherDependency otherDependency)
{
this.dependency = dependency;
this.otherDependency = otherDependency
}
public bool Matches(Type type)
{
return type==typeof(MyType)
}
public void Execute()
{
// do action using dependency/dependencies
}
}
Register Commands with Container
In StructureMap (use your favorite container), I would register the array like so:
Scan(s=>
{
s.AssembliesFromApplicationBaseDirectory();
s.AddAllTypesOf<IAttributeCommand>();
s.WithDefaultConventions();
}
Select and Execute Commands Based on Type
Finally, on the base class, I define an IAttributeCommand array in my constructor arguments to be injected by the IOC container. When the derived type passes in the types array, I will execute the correct command based on the predicate.
public abstract class MyController : Controller
{
protected IAttributeCommand[] commands;
public MyController(IAttributeCommand[] commands) { this.commands = commands); }
protected void DoActions(Type[] types)
{
foreach(var type in types)
{
var command = commands.FirstOrDefault(x=>x.Matches(type));
if (command==null) continue;
command.Execute();
}
}
}
If you multiple commands can handle one type, you can change the implementation: commands.Where(x=>x.Matches(type)).ToList().ForEach(Execute);
The effect is the same, but there is a subtle difference in how the class is constructed. The class has no coupling to an IOC container and there is no service location. The implementation is more testable as the class can be constructed with its real dependencies, with no need to wire up a container/resolver.