I am having problems injecting IWindsorContainer as a property.
I am using MVC3. I have created my own IView and ViewEngine. From within the View I dynamically build views based on the types registered in Windsor.
For one condition ( a "list" view) I want to display a list of all the IMyTypes registered with Windsor.
In my global.asax I register the Windsor view like this:
container.Register(Component.For<IWindsorContainer>().Instance(container));
Then in my IView implementation, I declare a property like this:
public IWindsorContainer Container { get; set; }
The actual IView is in another component. When I get to the Render method, I want to do this:
IRuleDataDefinition[] ruleDatas = Container.ResolveAll<IRuleDataDefinition>();
But "Container" is always null. Is it because of the way I am creating the IView (I am just using new, it isn't registered with Windsor?) Is it something with the IWindsorContainer itself? Or do I just have everything wrong?
I've also read other people that say "if you are using Container.Resolve you are probably doing it wrong." So if I am doing this wrong, please let me know.
EDIT
Perhaps a better way to phrase the question is: What is the best way to do the equivalent of container.ResolveAll() when you don't have a reference to the container? I need to loop through all registered versions of IMyType.
EDIT THE 2ND
I got it to work by using Windsor for the entire dependency chain, which, of course, is what you are supposed to do, I learned.
You should not have a dependency on the Container... that's an anti-pattern and it smells like a service locator.
What about a typed factory instead? Your typed factory may return a list of given components based on a common interface.
Related
I am using MVVM light and figured out since that the ViewModelLocator can be used to grab any view model and thus I can use it to grab values.
I been doing something like this
public class ViewModel1
{
public ViewModel1()
{
var vm2 = new ViewModelLocator().ViewModel2;
string name = vm2.Name;
}
}
This way if I need to go between views I can easily get other values. I am not sure if this would be best practice though(it seems so convenient makes me wonder if it is bad practice lol) as I know there is some messenger class thing and not sue if that is the way I should be doing it.
Edit
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<ViewModel1>();
SimpleIoc.Default.Register<ViewModel2>();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public ViewModel1 ViewModel1
{
get
{
return ServiceLocator.Current.GetInstance<ViewModel1 >();
}
}
Edit
Here is a scenario that I am trying to solve.
I have a view that you add price and store name to. When you click on the textbox for store name you are transferred to another view. This view has a textbox that you type the store you are looking for, as you type a select list get populated with all the possible matches and information about that store.
The user then chooses the store they want. They are transferred back to the view where they "add the price", now the store name is filled in also.
If they hit "add" button it takes the price, the store name, and the barcode(this came from the view BEFORE "add price view") and sends to a server.
So as you can see I need data from different views.
I'm trying to understand what your scenario is. In the MVVMlight forum, you added the following context to this question:
"I have some data that needs to be passed to multiple screens and possibly back again."
For passing data between VMs, I would also - as Matt above - use the Messenger class of MVVMLight as long as it is "fire and forget". But it is the "possibly back again" comment that sounds tricky.
I can imagine some scenarios where this can be needed. Eg. a wizard interface. In such a case I would model the data that the wizard is responsible for collecting and then bind all Views to the same VM, representing that model object.
But that's just one case.
So maybe if you could provide a little more context, I would be happy to try and help.
Yes, you can do this, in as much as the code will work but there is a big potential issue you may run into in the future.
One of the strong arguments for using the MVVM pattern is that it makes it easier to write code that can be easily tested.
With you're above code you can't test ViewModel1 without also having ViewModelLocator and ViewModel2. May be that's not too much of a bad thing in and of itself but you've set a precedent that this type of strong coupling of classes is acceptable. What happens, in the future, when you
From a testing perspective you would probably benefit from being able to inject your dependencies. This means passing, to the constructor--typically, the external objects of information you need.
This could mean you have a constructor like this:
public ViewModel1(string vm2Name)
{
string name = vm2Name;
}
that you call like this:
var vm1 = new ViewModel1(ViewModelLocator.ViewModel2.name);
There are few other issues you may want to consider also.
You're also creating a new ViewModelLocator to access one of it's properties. You probably already have an instance of the locator defined at the application level. You're creating more work for yourself (and the processor) if you're newing up additional, unnecessary instances.
Do you really need a complete instance of ViewModel2 if all you need is the name? Avoid creating and passing more than you need to.
Update
If you capture the store in the first view/vm then why not pass that (ID &/or Name) to the second VM from the second view? The second VM can then send that to the server with the data captured in the second view.
Another approach may be to just use one viewmodel for both views. This may make your whole problem go away.
If you have properties in 1 view or view model that need to be accessed by a second (or additional) views or view models, I'd recommend creating a new class to store these shared properties and then injecting this class into each view model (or accessing it via the locator). See my answer here... Two views - one ViewModel
Here is some sample code still using the SimpleIoc
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<IMyClass, MyClass>();
}
public IMyClass MyClassInstance
{
get{ return ServiceLocator.Current.GetInstance<IMyClass>();}
}
Here is a review of SimpleIOC - how to use MVVMLight SimpleIoc?
However, as I mentioned in my comments, I changed to use the Autofac container so that my supporting/shared classes could be injected into multiple view models. This way I did not need to instantiate the Locator to access the shared class. I believe this is a cleaner solution.
This is how I registered MyClass and ViewModels with the Autofac container-
var builder = new ContainerBuilder();
var myClass = new MyClass();
builder.RegisterInstance(myClass);
builder.RegisterType<ViewModel1>();
builder.RegisterType<ViewModel2>();
_container = builder.Build();
ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(_container));
Then each ViewModel (ViewModel1, ViewModel2) that require an instance of MyClass just add that as a constructor parameter as I linked initially.
MyClass will implement PropertyChanged as necessary for its properties.
Ok, my shot at an answer for your original question first is: Yes, I think it is bad to access one VM from another VM, at least in the way it is done in the code example of this question. For the same reasons that Matt is getting at - maintainability and testability. By "newing up" another ViewModelLocator in this way you hardcode a dependency into your view model.
So one way to avoid that is to consider Dependency Injection. This will make your dependencies explicit while keeping things testable. Another option is to use the Messenger class of MVVMLight that you also mention.
In order to write maintainable and testable code in the context of MVVM, ViewModels should be as loosely coupled as possible. This is where the Messenger of MVVMLight can help. Here's a quote from Laurent on what Messenger class was intended for:
I use it where decoupled communication must take place. Typically I use it between VM and view, and between VM and VM. Strictly speaking you can use it in multiple places, but I always recommend people to be careful with it. It is a powerful tool, but because of the very loose coupling, it is easy to lose the overview on what you are doing. Use it where it makes sense, but don't replace all your events and commands with messages.
So, to answer the more specific scenario you mention, where one view pops up another "store selection" view and the latter must set the current store when returning back to the first view, this is one way to do it (the "Messenger way"):
1) On the first view, use EventToCommand from MVVMLight on the TextBox in the first view to bind the desired event (eg. GotFocus) to a command exposed by the view model. Could be eg. named OpenStoreSelectorCommand.
2) The OpenStoreSelectorCommand uses the Messenger to send a message, requesting that the Store Selector dialog should be opened. The StoreSelectorView (the pop-up view) subscribes to this message (registers with the Messenger for that type of message) and opens the dialog.
3) When the view closes with a new store selected, it uses the Messenger once again to publish a message that the current store has changed. The main view model subscribes to this message and can take whatever action it needs when it receives the message. Eg. update a CurrentStore property, which is bound to a field on the main view.
You may argue that this is a lot of messaging back and forth, but it keeps the view models and views decoupled and does not require a lot code.
That's one approach. That may be "old style" as Matt is hinting, but it will work, and is better than creating hard dependencies.
A service-based approach:
For a more service-based approach take a look at this recent MSDN Magazine article, written by the inventor of MVVMLight. It gives code examples of both approaches: The Messenger approach and a DialogService-based approach. It does not, however, go into details on how you get values back from a dialog window.
That issue is tackled, without relying on the Messenger, in this article. Note the IModalDialogService interface:
public interface IModalDialogService
{
void ShowDialog<TViewModel>(IModalWindow view, TViewModel viewModel, Action<TViewModel> onDialogClose);
void ShowDialog<TDialogViewModel>(IModalWindow view, TDialogViewModel viewModel);
}
The first overload has an Action delegate parameter that is attached as the event handler for the Close event of the dialog. The parameter TViewModel for the delegate is set as the DataContext of the dialog window. The end result is that the view model that caused the dialog to be shown initially, can access the view model of the (updated) dialog when the dialog closes.
I hope that helps you further!
I have an ASP.NET MVC 3 application with Ninject v2.2.1.4. Everything was working great and then suddenly we started seeing Ninject attempting to create our DbContext using a constructor with a parameter over the parameterless constructor. Here are the bindings:
kernel.Bind<MyContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());
kernel.Bind<DbContext>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());
The MyContext is a DbContext object that implements the IUnitOfWork interface as well. I have set it up this way so the same context is injected into multiple repositories that are used in a single request. The MyContext constructors look like this:
public MyContext() { }
public MyContext(string connectionString) { }
public MyContext (long accountID) { }
public MyContext (Connection connection) { }
There are different constructors for different applications as they all use the same MyContext class. Looking at the bindings you would think when a MyContext class was requested that the parameterless constructor would be called but for whatever reason, it is not. The one with the long accountID parameter is called even though no accountID is being specified. This obviously throwns and exception statement that "No matching bindings are available, and the type is not self-bindable" It actually throws the exception when trying to generate a IUnitOfWork.
If I comment out the last three constructors everything works fine and the parameterless constructor is used. If I comment out any two of the parameterized constructors it tries to use the other and not the parameterless one.
The suggestions provided by Ninject are:
Suggestions:
1) Ensure that you have defined a binding for long.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
We don't have anything for 1 as we don't want to. I'm not sure what 2 and 5 mean. I do not believe we have done 3 and we are not doing 4.
Any thoughts as to why it wouldn't use the parameterless constructor in this scenario.
#Xander's answer is right in general but Ninject has some very specific solutions in V3.
Ninject scores constructors by a specific algorithm which is to find the one with the most parameters it knows how to resolve as documented in this wiki article [which claims to be for V2.4, which was actually badged 3.0]. See the code. I think this is also on the wiki. If it's not, someone should put it there.
RE the change in behavior you've seen, the chances are either Implicit Self Binding is changing the goalposts (new registrations are being added during resolution) or you've added a Binding that has made one of the other constructors more attractive.
The [Inject] attribute trumps all other criteria which is what you're after (although you don't actually want to have container specific attributes in your code).
The WithConstructorArgument technique suggested is actually effected by using ToConstructor - doing a WCA will not influence the selection (and I reckon you won't get complaints about the redundant specifications.
The real bottom line is that you should never end up in as big a mess as this as alluded to in #Mark Seemann's comment on this related question.
Sadly, the above is all a lie. If you move off v2.2, this answer will become correct. If you can't or won't, you need to look at the equivalent source and tests to find out the rules from before that (from memory (and some google code that appeared in search results in my research), it was based on the constructor count, but not sure how equal scores are disambiguated.
Pretty sure that in 2.2, adding an [Inject] is the quick way out.
By default Ninject, along with other similar IoC frameworks, chooses the constructor with the most parameters. Specify which constructor to use during the initialization by the WithConstructorArgument extension method.
kernel.Bind<DbContext>()
.WithConstructorArgument("connectionString",
ConfigurationManager.ConnectionStrings["connection"]
.ConnectionString)
.ToMethod(ctx => ctx.Kernel.Get<MyContext>());
To force Ninject to use the default constructor place the [Inject] attribute on the constructor:
[Inject]
public MyContext() { }
I'm very new to RavenDB and MVC3, in particular the usage (not concept) of IoC. So just to warn you that this will sound like a very beginner question.
In summary:
I have a domain model, let's say it's
public class Goose
Within this class I might have a more complex object as a property
public Beak beak { get; set; }
In RavenDB we are rightly encouraged to [JsonIgnore] this property or not have it at all and instead have a reference identifier, like
public String beakId { get; set; }
Somwhere along the way in my MVC3 application I will want to view the Goose and I might want to display to the user, something about the Goose and it's Beak (should that be Bill?). So yeah I need a view model right?
public class GooseModel
{
public String BeakColour { get; set; }
public String BeakLength { get; set; }
...etc
}
Right, so assuming I have some GooseRepository and some BeakRepository here's the simple question....
I'm in the GooseController class and I'm loading a Goose to view. At what point do I use the BeakRepository and who should know about it? The GooseController knows about the GooseRepository and is loading the Goose by id. At this point we could have some property inside the Goose class which represents the whole Beak, but I don't really want to inject the BeakRepository into the GooseRepository do I? Ok, so perhaps when I create the GooseModel from the Goose I've found I could get the GooseModel properties for the BeakColour and BeakLength, how? Well I like AutoMapper, so perhapds my Map For the GooseModel from Goose is using the BeakRepository to find the Beak and then extract the two Beak properties to populate the GooseModel fields.. this too seems wrong... so what's left? The GooseController.. should the Goose controller know about the BeakRespository and then find and set the BeakColour and BeakLength!? that certainly seems completely wrong too..
So where does it get done? the Controller, the domain object, the mapper or somewhere else? Perhaps I should have a partial view of Type Beak which is used within the Goose view?..
I tend to consolidate this kind of logic into a service/business layer (GooseService) that i then inject into the controller. your service layer might take a GooseRepository and a BeakRepository, and return a resolved object that has mapped the GooseViewModel together.
Uhm,... reading your question I strongly suggest you forget about the Service-Layer and the Repository-Layer. If you don't have really good reasons to keep them (testing is not one of them since RavenDB has an EmbeddableDocumentStore, which is fast and easy) pull them in order to take advantage of some very nice features of RavenDB.
I've actually written a post about why I think you should generally avoid these layers:
http://daniellang.net/keep-your-code-simple/ It is about NHibernate, but concepts apply here as well.
Whether you should denormalize the BeakColor and BeakLength property into your Goose-document depends on your applications need. If you feel comfortable with the term "aggregate root", then the rule of thumb is that these generally are your documents. If you're not sure whether denormalization should be applied, avoid it, and use .Include(goose => goose.Beak) instead when loading your Goose.
Please let me know if that makes sense to you.
I'm working on a large Asp.Net MVC3 application (>50 views) and we are currently planning on using Unity for our dependency injection framework. For ease of maintenance, I would like to be able to query the assembly to find all of the base types, then register them with Unity.
Based on sample code from the Unity MVC3 Project for registering all controllers, I tried the following code -
var orchestratorTypes = (from t in Assembly.GetCallingAssembly().GetTypes()
where typeof(IOrchesratorBase).IsAssignableFrom(t) &&
!t.IsAbstract
select t).ToList();
orchestratorTypes.ForEach(t => container.RegisterType(t);
When I run the application I get the following error message
The current type, WwpMvcHelpers.BaseClasses.IOrchesratorBase, is an interface and cannot be constructed. Are you missing a type mapping?
If I register the class using individually, as below -
container.RegisterType<IOrchesratorBase, HomeOrchestrator>();
Everything works correctly. Is there a way to do this so that I don't have to register each type individually?
EDIT
Per request, my inheritance hierarchy is
HomeOrcestrator <- IOrchesratorBaseList<LocalModel>
<- OrchesratorBase<LocalModel> <- IOrchesratorBase
The usage in the controller is
public class HomeController : ControllerListBase <HomeOrchestrator, LocalModel>
{
public HomeController() {}
public HomeController(IOrchesratorBase homeOrchestrator) {
this.Orchestrator = (HomeOrchestrator) homeOrchestrator;
}
The LINQ to get the types appears to work. I don't think that's your problem.
You'll get a similar error if you just write
container.RegisterType(typeof(HomeOrchestrator));
and call container.Resolve<IOrchesratorBase>().
In other words, RegisterType(t) is not the same as RegisterType<I, T>().
The real question is, what are you resolving and how do you want it resolved? Your query is finding implementors of IOrchesratorBase. Are your injection constructor parameters of that type? If so, what's Unity supposed to do when 20 types implement that interface?
Can you provide more information on your class/interface hierarchy, constructor parameters, and what you expect/want to happen?
(I'd refactor to change IOrchesratorBase to IOrchestratorBase, BTW.) :)
Edit
Based on the edited question, the problem is that, in order to resolve a HomeController, Unity is looking for a type registration for IOrchesratorBase. It determines the interface type by the parameter types of the constructor with the most parameters.
If you write container.RegisterType<IOrchesratorBase, HomeOrchestrator>() the answer is obvious - Unity will construct an instance of HomeOrchestrator and inject it.
Now, is there more than one type that implements IOrchesratorBase? If so, and you register both of them (explicitly), Unity will use whichever one you register last. That may not be what you want.
If you have multiple controllers, each taking a different interface type in their constructors (with only one implementation per interface), you'll need to figure out what each interface type is and re-run your LINQ registration for each one. That could be done via reflection - find the orchestrators or the controllers.
If you have multiple controllers, each taking the same interface type in their constructors and you want different implementations for each, you've got a problem. You'd have to register named types and determine the names somehow, or something similar.
Unity isn't magic. It can't figure out your intentions.
Addendum
Unity can operate in a convention-over-configuration mode; see Using Unity With Minimal Configuration.
Using Castle.Windsor in ASP.NET MVC (3.0) is there any way I can appropriately handle if one of my dependencies resolves null? For instance, say I have a IMembershipService.
class ServiceInstaller
{
// ...
void Install( // .. )
{
container.Register(
Component
.For<IMembershipService>()
.ImplementedBy<MembershipService>()
.LifeStyle.PerWebRequest
);
}
}
Okay, this works great. Now, perhaps not all of my site requires a user to be logged in. Let's assume that maybe my web host's database server crashes for a few hours. In that event, things that looked into the database, or tried to call on my ISession might return null.
What can I do in this case? I can write if(membershipService == null) a hundred times over, but that seems pretty dumb. Is there a built-in solution to say "Hey, if we have an error, do this..?"
I think that the service should never be null. If the database is down, the service should be returned nevertheless, but its methods should throw an exception, return null or some default value, depending on the semantic of the service.
Ciel, i had this problem just recently and found your question while looking for the answer.
Basically you should be using a typed factory to resolve your components at runtime in your wrapping component. The factory should return a default object if there is no match regarding the component you're looking for, default object that would implement whatever behavior is needed.
In the case of your IMembershipService, implement a NotCheckingMembershipService class inheriting the interface and doing nothing and make it the default for the components that won't need it. More specific membership services can be linked to specific controllers.
To do so you must create a generic "catch-all" implementation
public class NotCheckingMembershipService<T>: IMembershipService<T> where T: Controller
{
}
And register it as the default component for an open IMembershipService
_container.Register(
Component.For(typeof(IMembershipService<>))
.ImplementedBy(typeof(NotCheckingMembershipService<>))
.IsDefault());
Then simply register your custom membership services where needed. Resolution won't fail and you will always be able to call the interface.