Prism 7 throws ResolutionFailedException: No public constructor available for type (Interface) - mvvm

I'm devolping a WPF application, using Prism 7.2. I have a module, which implements the IModule interface, where I register the views and viewmodels in the RegisterTypes method, e.g.:
containerRegistry.Register<IPanelOptimizationViewModel, PanelOptimizationViewModel>();
The problem arises when I try to resolve the implementation:
var vm = containerProvider.Resolve<IPanelOptimizationViewModel>();
whereupon I get the following Unity.ResolutionFailedException:
'Resolution failed with error: No public constructor is available for type
XXX.Infrastructure.Interfaces.IView.'
The PanelOptimizationViewModel class derives from a base class:
public class PanelOptimizationViewModel : ViewModelBase, IPanelOptimizationViewModel
{
public PanelOptimizationViewModel(IPanelOptimizationView view, IPanelOptimizationInputViewModel inpVM) : base(view)
}
and the ViewModelBase looks like this:
public class ViewModelBase : BindableBase, IViewModel
{
public IView View { get; set; }
public ViewModelBase(IView view)
{
View = view;
View.ViewModel = this;
}
}
The interfaces IView and IViewModel are defined in a common Infrastructure project. They are not registered anywhere in the container, but if I remove the IPanelOptimizationInputViewModel parameter, no runtime exception is thrown - leading me to think that I don't need to do this, either.
As far as I have been able to understand, the Unity.Container will use the "most parameterized" constructor (see Unity not using the default constructor of the class), but I cannot provide a parameter in the Register method to specify this, as one apparently could before (pre Prism 7's container abstraction), with the RegisterType method.
How to solve this? Is there an overload of the Prism.Ioc.IContainerRegistry.Register method that allows me to set up the registration for constructor injection?
Should I work directly with the Unity container?
Basically, I am trying to inject a child view's viewmodel into the constructor of my "main" viewmodel, but this does not go well as long as the wrong constructor is called on the base class, with the wrong set of parameters... (if that is what is happening).
Needless to say, all child views and viewmodels have been registered in the RegisterTypes method in the module.
Any help on this would be greatly appreciated

Should I work directly with the Unity container?
Yes, you can evade Prism's "abstraction" of the container by calling the GetContainer() extension method (for your container).
containerRegistry.GetContainer() // here you get a plain IUnityContainer
.RegisterType( ... );

Related

Interface binding to the ViewModel without MVVM packages

I want to call a service interface in the ViewModel constructor without using any libraries for MVVVM like MVVMLight etc like
public HomePageViewModel(IHomeService homeService)
{
}
This is how we do it using a MVVM light.
IService _tService;
public HomePageViewModel(IHomeService homeService, INavigationServiceExtended navigationService, IService tService)
{
_tService=tService;
}
How can I get the send the IHomeService instance from the view while binding the View to the ViewModel .
When using DI you either inject the dependency in the calling code, in your case you do something like this:
var homePageViewMdel = new HomePageViewModel(new HomeServiceImplementation());
Or either you would use an IoC container like (Unity, DryIoc or Autofac) or write your own IoC from scratch.

Migrating from Unity, how to do Property or MethodInjection on all classes without registering them

Ok, lets first be clear that I know this is not correct way (use constructor injection). I do have a huge codebase to take care of and a refactoring is not an option right now.
I have a base class
public abstract class ServiceBase {
public IUnitOfWork UnitOfWork {get;set;}
}
and a lot of Concrete classes that are NOT registered in the contianer.
public class ServiceScript : ServiceBase {
}
How do I inject IUnitOfWork??
I have alot of this ServiceScript-classes that are not registred in the Container
but is using the AnyConcreteTypeNotAlreadyRegisteredSource in Autofac
In unity I did just mark my PropertyDependency with a [Dependency]-attribute and everything just works.
It looks like StructureMap has the same way of using attributes, but they don't have Prism/Xamarin-support, like Autofac has.
This same problem can be applied to a ControllerX : ControllerBase in asp.net core.
I have tried to solve this with a RegistrationSource, but can't get it to work in the controller case that I tried first.
Any input??
/Peter

GIN #Inject on variable for Rpc Services

I'm a bit lost with the use of Inject on variable.
I got this code working :
private XXServiceAsync xxServiceAsync;
#Inject
protected IndexViewImpl(EventBus eventBus, XXServiceAsync tableManagementServiceAsync) {
super(eventBus, mapper);
this.xxServiceAsync = xxServiceAsync;
initializeWidgets();
}
With this code, I can call my RPC service wherever I need in the class (On click ...)
I would like to clear a bit the code by injecting direcly in the variable ; doing so :
#Inject
private XXServiceAsync xxServiceAsync;
protected IndexViewImpl(EventBus eventBus) {
super(eventBus, mapper);
initializeWidgets();
}
This always keep the Service to NULL.
Am I doing something wrong ? Is the GIN magic with rpc services meant to be done otherwise?
Thanks!
It is still null at that point, because Gin (and Guice, and other frameworks like this) cannot assign the fields until the constructor has finished running.
Consider how this would look if you were manually wiring the code (remember that Gin/Guice will cheat a little to assign private fields, call non-visible methods):
MyObject obj = new MyObject();//initializeWidgets() runs, too early!
obj.xxServiceAsync = GWT.create(xxService.class);
If you need something in the constructor, pass it into the constructor. If you wont need it right away (such as until asWidget() is called), then a field or setter annotated with #Inject can be helpful.
If you have field level injection you can use an empty #Inject method to do your post-inject initialization. The no-arg injected method will be run after field injections on the class are complete.
#Inject void initialize(){
...
initializeWidgets()
}
Edit: I previously stated that it was run after method injection as well, but testing shows that this is not always the case.

MVVM share object between the all the views

I have MVVM Project and I want to share one object( singleton ) from the model between several viewmodel what is the good practice to do that?
Thank you for the help
If the object is needed and does not provide value without it force the interface within the object via Constructor Injection; do not push a concrete type via injection always make use of an interface.
Since you are not making use of an IoC container such as Unity, you will need to create your singleton instance at the startup of your application and then make sure that the given instance is passed in via the given ViewModels constructor as needed.
A better approach would be pushing the singleton instance to a service which can provide the needed behavior and then disregard pushing the singleton into the Model. This would be a more MVVM purist approach and will separate concerns across your Models/ViewModels.
EDIT:
If you were making use of Unity you would define a Lifetime Manager at the time of registration.
// Register a type to have a singleton lifetime without mapping the type
// Uses the container only to implement singleton behavior
myContainer.RegisterType<MySingletonObject>(new ContainerControlledLifetimeManager());
// Following code will return a singleton instance of MySingletonObject
// Container will take over lifetime management of the object
myContainer.Resolve<MySingletonObject>();
Once you do this any attempt to resolve MySingletonObject via the IUnityContainer would resolve to the same instance providing the singleton behavior you so desire across the application. ViewModels themselves should not need to have the same instance returned. The data it needs should be abstracted away via a service as referenced earlier which could potentially behave like a singleton and provide a stateful implementation if needed but the ViewModel should not need to be a singleton. If you find yourself making either a Model or ViewModel a singleton; take a step back and analyze your design.
If you have control over all viewmodels then an easy approach (that I've used personally) is to just put a static variable on the base class of all viewmodels and make that accessible to all inheritors (either protected or even public if its useful outside of the viewmodels).
It's good practice anyway to have a common base class for your viewmodels since it allows you to implement property notification in one place (and other common functionality, like messaging etc.) instead of replicating it in all viewmodels.
Something like this is what I've used in my projects:
public class MyViewModelBase : INotifyPropertyChanged
{
private static MySharedSingleton _sharedObj;
static MyViewModelBase()
{
_sharedObj = new MySharedSingleton(/* initialize it here if needed */);
}
// or public
protected MySharedSingleton SharedObject { get { return _sharedObj; } }
// INotifyPropertyChanged stuff
// ...
}
public class SomeViewModel : MyViewModelBase
{
void SomeMethod()
{
SharedObject.DoStuff();
}
}
If the construction of the shared singleton object is heavy, you can of course use any of the standard techniques for lazy instantiation of it.
I would suggest that you inject the dependency into each view model (either constructor or property injection for example), and always work against abstractions in your view models, so that your dependency can easily be mocked or replaced as required. You then just need to ensure that each view model uses the same instance of your type - if you are using an IoC container, you can register a shared instance of your type easily.
I use a separate class for my global singleton with a model. This relieves me of agonizing over how to inject this model into view models and other models. E.g.
The singleton:
public class ApplicationModel
{
public string LoggedOnUser { get; set; }
// Etc.
private ApplicationModel() {
// Set things up.
}
private static ApplicationModel _active;
public static ApplicationModel Current {
get {
if (_active == null) {
_active = new ApplicationModel();
}
return _active;
}
}
}
The view model that needs to hold no reference to the singleton:
public class SomeViewModel
{
private string _user;
public SomeViewModel() {
_user = ApplicationModel.Current.LoggedOnUser;
}
}

How do I use constructor dependency injection to supply Models from a collection to their ViewModels?

I'm using constructor dependency injection in my WPF application and I keep running into the following pattern, so would like to get other people's opinion on it and hear about alternative solutions.
The goal is to wire up a hierarchy of ViewModels to a similar hierarchy of Models, so that the responsibility for presenting the information in each model lies with its own ViewModel implementation. (The pattern also crops up under other circumstances but MVVM should make for a good example.)
Here's a simplified example. Given that I have a model that has a collection of further models:
public interface IPerson
{
IEnumerable<IAddress> Addresses { get; }
}
public interface IAddress
{
}
I would like to mirror this hierarchy in the ViewModels so that I can bind a ListBox (or whatever) to a collection in the Person ViewModel:
public interface IPersonViewModel
{
ObservableCollection<IAddressViewModel> Addresses { get; }
void Initialize();
}
public interface IAddressViewModel
{
}
The child ViewModel needs to present the information from the child Model, so it's injected via the constructor:
public class AddressViewModel : IAddressViewModel
{
private readonly IAddress _address;
public AddressViewModel(IAddress address)
{
_address = address;
}
}
The question is, what is the best way to supply the child Model to the corresponding child ViewModel?
The example is trivial, but in a typical real case the ViewModels have more dependencies - each of which has its own dependencies (and so on). I'm using Unity 1.2 (although I think the question is relevant across the other IoC containers), and I am using Caliburn's view strategies to automatically find and wire up the appropriate View to a ViewModel.
Here is my current solution:
The parent ViewModel needs to create a child ViewModel for each child Model, so it has a factory method added to its constructor which it uses during initialization:
public class PersonViewModel : IPersonViewModel
{
private readonly Func<IAddress, IAddressViewModel> _addressViewModelFactory;
private readonly IPerson _person;
public PersonViewModel(IPerson person,
Func<IAddress, IAddressViewModel> addressViewModelFactory)
{
_addressViewModelFactory = addressViewModelFactory;
_person = person;
Addresses = new ObservableCollection<IAddressViewModel>();
}
public ObservableCollection<IAddressViewModel> Addresses { get; private set; }
public void Initialize()
{
foreach (IAddress address in _person.Addresses)
Addresses.Add(_addressViewModelFactory(address));
}
}
A factory method that satisfies the Func<IAddress, IAddressViewModel> interface is registered with the main UnityContainer. The factory method uses a child container to register the IAddress dependency that is required by the ViewModel and then resolves the child ViewModel:
public class Factory
{
private readonly IUnityContainer _container;
public Factory(IUnityContainer container)
{
_container = container;
}
public void RegisterStuff()
{
_container.RegisterInstance<Func<IAddress, IAddressViewModel>>(CreateAddressViewModel);
}
private IAddressViewModel CreateAddressViewModel(IAddress model)
{
IUnityContainer childContainer = _container.CreateChildContainer();
childContainer.RegisterInstance(model);
return childContainer.Resolve<IAddressViewModel>();
}
}
Now, when the PersonViewModel is initialized, it loops through each Address in the Model and calls CreateAddressViewModel() (which was injected via the Func<IAddress, IAddressViewModel> argument). CreateAddressViewModel() creates a temporary child container and registers the IAddress model so that when it resolves the IAddressViewModel from the child container the AddressViewModel gets the correct instance injected via its constructor.
This seems to be a good solution to me as the dependencies of the ViewModels are very clear and they are easily testable and unaware of the IoC container. On the other hand, performance is OK but not great as a lot of temporary child containers can be created. Also I end up with a lot of very similar factory methods.
Is this the best way to inject the child Models into the child ViewModels with Unity?
Is there a better (or faster) way to do it in other IoC containers, e.g. Autofac?
How would this problem be tackled with MEF, given that it is not a traditional IoC container but is still used to compose objects?
Depending on the container can you not specify a parameter (named or otherwise) in your factory's CreateAddressViewModel method?
container.Resolve<IAddressViewModel>(new NamedParameterOverloads() { { "Address", model } };
Depending on the container your factory may have to know the name of the parameter (TinyIoC and Castle afaik), or it may had to be last in the list of constructor dependencies (YMMV depending on containers), which isn't great, but it saves creating a lot of child containers in quick succession, and the GC thrashing that will follow, and you still get DI for all your other dependencies.
Of course this falls down if your VM also has a dependency that requires the same IAddress, in that case a child container is probably the way to go unless you want the VM to have knowledge of the container.
Update:
If you're using a subcontainer of a container that uses "last register wins" (which I think Unity does), then you could pass the same child container into your Factory each time, and have your factory simply register the new IAddress - that way you wouldn't be creating a new UnityContainer instance on the heap for each iteration and it should cut down on garbage collections if you're creating lots of items.
The ViewModel sample application of the WPF Application Framework (WAF) shows how you could bring the Model and the ViewModel together. The sample uses MEF as Dependency Injection Framework.