I'm working on a Xamarin.Forms application that uses Prism 7. I have dependencies registered in the DI container as transient but is there any way to have them scoped to ViewModel like they are scoped to the current web request?
Related
I'm using Autofac IOC in my Asp.Net MVC Application. I have seen a circular dependency between services detected in run time (even not detected in building/rebuilding project). Why this happen in run time?
Autofac is not a compiler or compiler plugin. It is a library that uses reflection to gather information only available at runtime to build object graphs, and it only does so when you start your application.
If you want compiler support: don't use a DI Container, but revert to using Pure DI, which means you build your object graphs by hand (using new statements) inside the Composition Root.
I am currently developing a Xamarin Forms app and am in the process of reworking it to work with Prism. I'm really trying to adhere to MVVM design patterns (I'm trying to grow as an amateur developer and learn how to use them).
1) Is it improper from a MVVM design pattern perspective to utilize messaging services (Prism's EventAggregator) and UI interactions (Prism's PageDialogService) outside of VMs? I've written several "services" that are called from the VM and have found a need to access both messaging and UI services. As one example, The VM calls a service, the service retrieves and processes some data, ask a question to the user based upon those calculations and then continue to finish processing returning the desired value. To be proper, should control be returned back to the VM to "just" ask the question?
2) If it's not verboten, is it possible to access the services outside of VMs? It does not readily appear to me that I can inject them into the constructor of the service. Is it okay to "pass" them into the service's function I'm calling along with other parameters? That just seems un... MVVM-ish?
Update:
I'm not sure all my steps were necessary, but with the help below I got it working. First I converted my singleton service into an interface (IMyService) and an implementing class (MyService). Next, I overrode ConfigureContainer in App.xaml.cs and called Container.RegisterType<IMyService, MyService>(new ContainerControlledLifetimeManager());
I could then inject IMyService, just like IEventAggregator and IPageDialogService into my ViewModels and I could also inject those services into the public constructor of my implementing class (MyService).
ad 1) the event aggregator is meant primarily for UI, but you can use it as message bus in other parts of the app, too, if you don't need the more advanced features of a "real" message bus.
ad 2) unity will happily inject dependencies into services that are themselves dependencies of view models or other services. That's what a dependency injection container does :-)
I'm building a WPF application using MVVM pattern, and Caliburn.Micro is the framework choice to boost up the development.
Different from a conventional MVVM-based application, I add a business layer (BL) below the ViewModel (VM) layer to handle logic for specific business cases. VM is left with data binding and simple conversion/presentation logic. Below BL is an extra Data Access layer (DAL) that encapsulates the Data model (DM) underneath built with Entity Framework.
I'm pretty new to both WPF, MVVM and, of course, know almost nothing about Caliburn. I have read plenty of questions and answers about the Caliburn usage and now trying to use what I've learnt so far in my application.
My questions are:
Does it sound okay with the above layered architecture?
In the application bootstrapper, is it correct that we can register all services that will later be used (like EventAgreggator (EA), WindowManager or extra security and validation services), and also all the concerned VMs? These should be injected into VM instances via constructors or so (supposed I'll be using SimpleContainer). So from any VM that are properly designed and instantiated, we can have these services ready to be used. If I understand correctly, Caliburn and its IoC maintain a kind of global state so that different VMs can use and share it.
Navigation: I know this topic has been discussed so many times. But just to be sure I'm doing the right way: There'd be a ShellViewModel acting as the main window for the whole application with different VMs (or screens) loaded dynamically. Each VM can inherit either Screen or ViewModelBase or NotifyChangedBase. When I'm in, let's say, VM A and want to switch to VM B. I'd from inside VM A send a message (using EA) to the ShellViewModel, saying that I want to change to B. ShellViewModel receives the message and reloads its CurrentViewModel property. What should be a proper data structure to maintain the list of VMs to be loaded? How can stuffs like Conductor or WindowManger come into the place?
Can/Should Caliburn in one way or another support the access to the database (via EF). Or this access should be exposed to VM and/or BL only?
Thanks a lot!
Different from a conventional MVVM-based application, I add a business layer (BL) below the ViewModel (VM) layer
That's the standard case. ViewModels can't/shouldn't contain business logic which is considered to be part of the Model (Model in MVVM is considered a layer, not an object or data structure) in the MVVM. ViewModel is for presentation logic only.
Yes, as long as your Business (Domain) Layer has no dependency on the DAL (no reference to it's assembly). Repository interfaces should be defined in the Business Layer, their implementations in the Data Access Layer.
Yes, Bootstrapper is where you build your object graph (configuration the IoC container).
Registering ViewModels: Depends on IoC framework. Some frameworks let you resolve unregistered types, as long as they are not abstract or interfaces (i.e. Unity). Not sure about Caliburn, haven't used it. If the IoC supports it, you don't need to register them.
One possible way to do it. I prefer navigation services though, works better for passing around parameters to views and windows that are not yet instantiated and you always know there is exactly one objects handling it.
With messages, there could be 0, 1 or many objects listening to it. Up to you
What do you mean with support access to the database? You can use it to inject your repositories and/or services into your ViewModels, other than that there isn't much DB related stuff to it.
All,
There has been a lot of posts about Unity Lifetime Managers but I have yet to find someone state a good rule of thumb for "in these cases you should always use X". Let me describe my application, I have an ASP.NET MVC 4 Web Application. I have a Visual Studio solution containing 3 projects, my 'Core' project which has all of my EF stuff, a testing project, and the MVC Web Project. I am using Unity for dependency injection and have the following code right now:
// Context
container.RegisterType<IDatabaseFactory, DatabaseFactory>(
new ContainerControlledLifetimeManager();
container.RegisterType<UnitOfWork>(
new ContainerControlledLifetimeManager());
However, I'm noticing that my context is not recreated with every new web request which is what I think I would want (let me know if I'm wrong in that assumption). I'm having a hard time analyzing all of the information from the sites listed below and have read about a lot of people creating their own class named PerHttpRequestLifetimeManager to handle this.
What truly is the best practice here?
Understanding Lifetime Managers by Microsoft's Developer Network - http://msdn.microsoft.com/en-us/library/ff660872(v=PandP.20).aspx
MVC DI & Unity with Lifetime Manager via CodeProject - http://www.codeproject.com/Articles/424743/MVC-DI-Unity-with-Lifetime-Manager
ASP.NET MVC Tip: Dependency Injection with Unity Application Block via Shiju Varghese's Blog - http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx
MVC, EF - DataContext singleton instance Per-Web-Request in Unity via Stack Overflow - MVC, EF - DataContext singleton instance Per-Web-Request in Unity
Inject same DataContext instance across several types with Unity via Stack Overflow - Inject same DataContext instance across several types with Unity
Yes, you usually want one DbContext per request.
A PerHttpRequestLifetimeManager or child container created on every request are the typical ways this is handled.
The latest release of Unity introduces the Unity bootstrapper for ASP.NET MVC which has a new built-in lifetime manager: PerRequestLifetimeManager.
You can read more in the Developer's Guide to Dependency Injection Using Unity chapter 3, Dependency Injection with Unity.
Here's the current layout:
Solution:
Core
Domain
Interfaces
DataAccess
Providers
Session
Service
UI
UnitTests
IntegrationTests
I typically try to keep my core domain entities / POCOs as light as possible without very many external dependencies.. So I was thinking it might make sense to put it in the Service layer as it typically has a project reference to all of the layers.
I have noticed that in CodeCampServer they have actually created a separate project called DependencyResolution for their IoC configuration:
http://code.google.com/p/codecampserver/source/browse/trunk#trunk/src/DependencyResolution
Thoughts?
IOC configuration should be off to the side. It doesn't necessarily need to be in a separate project, but it needs to be away from the application code. We put it in another project in CodeCampServer to make 'off to the side' more real. But in a current production app, we keep it in a separate namespace in our main project. We consolidated projects to increase compile time.