I'm using Prism to build my application and 19 of my modules need to interact with an control from another module.
Is there any way to expose a control? I really don't want to use the event system because it would too much of the responsibility on my one know to know about the data being passed to it.
If you do not wish to use the event aggregator, you could also register something (ie a service, whos interface is defined in your infrastructure dll) with dependency injection that interacts with the control directly.
You can always create a separate project that holds "Infrastructure" controls that each module references. This way they gain access to say CommonWindow etc..
Related
I have developed a WPF application using Prism and Unity frameworks and I have some concerns regarding the following whether I have implemented them correctly or not.
Abstract classes / Interfaces - I have organized interfaces for all the layers in one assembly and then referenced it in the respective library for implementation. Now, the referenced library has access to all the non required interfaces of other layers. For e.g. the service layer has access to UI interfaces. Is this the proper implementation in terms of clear separation or should I split it into multiple assemblies.
View Model dependencies - I used EventAggregator mostly to communicate between view models. In some cases, I am passing the instance of other view models directly in the constructor and resolving it using DI container. I want to omit the direct view model dependency by introducing the interface to achieve clear separation. How can I organize the interface for view models into a separate assembly in such a way that the other developers could understand.To avoid creating multiple UI projects, I created only one single assembly and logically separated them into folders.
Abstract Module Class - Instead of specifying all the dependencies in bootstrapper.cs file, I factored them in respective module. Most of my class lib projects has references to Prism libraries. Thus, UI specific namespaces are added to non UI related projects. Is there any better approach to achieve this ?
Abstract classes / Interfaces
I'd go for exactly as many "interface-assemblies" as necessary, having too many of them hurts. Example: if you need to prevent layer 1 from potentially communicating with layer 3, put the layer 1-to-layer 2-interfaces in one assembly and those for layer 2-to-layer 3 in another one.
View Model dependencies
Normally, you shouldn't need to pass view models around at all. Pass around the data (a.k.a. model), the view models themselves don't hold any data that's either unavailable elsewhere or valuable to anyone but the view bound to the view model.
Abstract Module Class
Your prism application references prism... so what? As long as only the IModule implementations receive the IUnityContainer I wouldn't care at all. If someone needs to publish an event, he get's the IEventAggregator... That's an interface already, and you can inject a mock in your tests, so no need for further abstraction.
I have developed a Microsoft Prism 4.0 application and I am struggling to understand how to make the user application setting functionality available to modules.
e.g. a Properties.Settings.Default.MyProperty.
I can define a simple class that gets populated via the bootloader (which does have a handle to the properties) and inject that into the modules but If I want to save a change of property, I need believe I need a handle to the Properties.Settings context which is not available to my modules (which are simple class libraries).
Your scenario sounds like the perfect reason to use a "Service" class. Create an interface and class called IUserSettingsService and UserSettingsService that has the information (or can load and save it from where it is stored).
Read Chapter 3 of the Prism 4.0 help file, Managing Dependencies Between Components, Registering Types with (either Unity or MEF, depending on what you are using as your DI Container).
Then, in your ViewModel that needs the user settings, locate and use your service. In MEF, it is as simple as adding a property of type IUserSettingsService with an [Import] attribute, or using [ImportingConstructor] and having a parameter of type IUserSettingsService. With Unity, you access the service through the container. See Chapter 10 of the Prism help file - Advanced MVVM Scenarios.
Added after comment discussion:
Because you need your service to be in the context of your main application, you can implement your service class there. Create the interface for your service in a shared library that can be used by both the main project and your modules. Finally, load the service in the bootloader class instead of in a module.
I am building an application in the MVVM style where the actual views (UserControls) are stored remotely and hopefully sent via a WCF service to my main application window. I am doing this in order to avoid having the user reinstall the application each time a new view is added. However, when I try to return a User Control from my WCF service I get an error stating:
System.Runtime.Serialization.InvalidDataContractException: Type 'System.Windows.Input.TouchDevice' cannot be serialized.
I am wondering if there is any way around this or if people have implemented something similar in other ways?
Thanks,
Ochowie
When you're loading from an assembly you're instantiating the compiled object from an assembly, which is a lot different than a deserialization operation, which is what is happening with a service call. The best you can do with serialization is transfer raw XAML that can be loaded with XamlReader, but this limits what you can do with a control since you can't use any code. If you're really set on hosting controls on your server the most flexible option would be to have your app download an assembly containing the new control and dynamically load the new assembly or use a separate launcher that can download new control assemblies before starting up the main application (make sure you take the time to understand the security implications and secure the assemblies and downloads).
What you're trying to do doesn't really make sense... controls are not DTOs, they're strongly dependent on their runtime environment. In WPF, there is also the issue of the dispatcher : even if you could transfer a control, how would you reattach it to your application dispatcher ? Anyway WPF controls are not serializable with the DataContractSerializer, and there is no way to change that.
However, what you could do is transfer a representation of the views in XAML. This is of course assuming your views are XAML only, without any code-behind. You could then load the views using XamlReader and render them in your UI. I'm not sure of the feasibility, but I think it's your best option.
You could also implement your views in a separate assembly, so that the users don't need to reinstall the whole application. They will only need to upgrade the modified assemblies.
I'm about to use a user control developed by a different team (in the same company) and for the app we're developing we're attempting to describe all the data binding in XAML.
Now if I use a third party user control should I expect them to supply a basic ViewModel with hooks for my code or should I expect to write code to bind the user control to a ViewModel of my choice?
Cheers
AWC
It depends on the scope of the UserControl. If it is particular to the application and is unlikely to be useful elsewhere then yes, a public ViewModel should probably be supplied.
However, a public ViewModel is likely to be less useful where the control is expected to be re-usable. The control may use a ViewModel internally, but this should be kept private. Then the host application uses the control in a similar way to any other WPF control, and creates it's own view model to tie the control to the application.
In essence, a ViewModel is usually particular to an application - it is tailored specifically to the needs of that application. Whereas general purpose controls expose properties and events that allow them to be used in any application.
Write the controller class yourself. A reusable control should not know which type of data it's working with, unless it's specifically written for it. But then it wouldn't be very reusable :)
The control is supplied as a self contained unit. If it has it's own viewmodel internally which has hooks exposed that is all great, but to you it doesn't matter because you cannot manipulate it directly.
If you really feel the need then you should write your own viewmodel for the supplied control, as this abstracts the UI (the supplied control) from the controller (your code). That is one of the purposes of the pattern - to separate concerns, so you can swap out any part with minimal effect on the remaining parts.
But having said that, not every control is going to need its own viewmodel, instead you would use the supplied control as part of a larger user control, and write a viewmodel for that larger control.
I would like to use Ninject in my WinForms application. I cannot figure out how to use it for my user controls. Sometimes they rely on the services I want to configure through the DI framework. These controls need to be manageable through the designer (thus need default constructors).
So, is there a way to inject dependencies into properties of this user control? Since the designer needs to be able to construct it, kernel.Get<TestClass> won't work here. Is there a method or some code that will let me "fill-in" the dependencies in the Form_OnLoad() method?
I can also think of other examples where I would want to Inject into the properties of an already existing object, but th WinForms user control is the easiest to explain.
I think you need to invert your thinking. In Model View Controller, the View has only one responsibility: to display data.
How that data gets there is the Controller's responsibility, and how the data is represented in memory is determined by the Model.
Although there are no specific MVC frameworks for Windows Forms, it's possible to make crude ones manually, or you could go have a look at the (now retired) Composite Application Block to get an idea about how this can be done (although the CAB is perhaps too complicated for most people's tastes). There are more elegant options available today, but they involve WPF.
In any case, instead of injecting your dependencies into your Views, inject them into Controllers, and have the Controllers instantiate and correctly populate the Views (your Controls).
In this way, you can keep your Controls free of DI concerns, as they should be.
I think the question is what DI tool can you use to get dependency injection to work with windows forms. Everyone does the MVC example because it's easy to implement(the same example if floating around the we as if it were new and original). If you have an answer for doing it using winforms or even WPF - that would be helpful.
This answer here basically says - in any case, I don't know so inject them into controllers and populate the views - really? Back to the MVC? Again - winforms.