ObservableCollection in the service layer of the WPF MVVM application - c#

Examples of WPF MVVM apps I've seen on the Internet consider VM a layer which interacts with a service layer which either uses "old" events from an external library, or interacts with web using HTTP or whatever. But what if I build all M, V, VM, service and other parts myself? How to properly build interaction between the service layer and the viewmodel layer? Can I just put ObservableCollection<OrderModel> into the service and return it as is from the viewmodel for the view, or is it considered a bad approach and there're better alternatives?

You can do this - of course you can. The primary reason to do such a thing would be to reduce duplication across multiple WPF applications.
However, a challenge you might have in some scenarios, depending on your service layer/data layer implementation, is long-running services that in turn use database connections. ObservableCollections are enticing from the point of view of having the service layer automatically synchronising changes made by an application to a data store; however it gets complicated when you want to communicate changes that originate from the data itself (i.e. in response to some other process that creates/modifies data).
The service layer can't really replace the instance (i.e. in the case of large-scale changes), since it is no longer the sole owner of the reference - but even if it could, replacing the instance would pretty much break any binding the UI has to the collection.
So you stick to trying to keep the one instance up to date. If your services are bound to a database, then unless you code-up some form of long-running monitoring process within your service, the only simple way to keep an ObservableCollection up to date after it's been dished out would be to hold database connections/contexts (in the case of Linq to Sql or EF) open - because otherwise related objects etc are not going to be able to retrievable (unless you force all objects to be read in one go - which is not scalable).
Okay, so it's possible to write some form of management layer which can manage the connections for you - but in addition to the inevitable polling, or perhaps SQL Server notifications that you might use, I believe the code might get quite complicated.
That said, it really does depend - that particular issue is one to look out for, but it might be that you have an architecture and environment in which such things simply don't matter.
My advice, if you want to try it - go ahead. For me? I've thought about it - and beyond adding INotifyPropertyChanged to some domain models, I stick to the idea that an application has it's own VM. Multiple applications might share the same VM - but that won't be internal to the service layer itself.
A service layer provides access to data and business logic in a typically one-shot way. Classes in the VM pattern are intended to have a much longer lifespan - and trying to code a long-running service layer is notoriously very hard to do - especially if you want it to try and solve all the problems that all future applications might present. Inevitably you will end up coding services or VM types within the service layer for a single application only - in which case it might as well have gone in that App's codebase.

I'd be tempted to use an ObservableCollection only from the point at which the "observable" aspect is relevant, which is generally the VM exposing something to the V. Further down the stack (i.e. the M) I'd be tempted to stick with more generic things like lists and collections (unless you specifically need for things to be otherwise). Its easy enough for the VM to create an ObservableCollection based on any old IEnumerable in any case.
A reasonable question though, especially as ObservableCollection's placement in the System.Collections namespace would seem to suggest that Microsoft don't particularly think of this as a specialized class (and certainly not wpf-specific).

I wouldn't do that for a number of reasons. They're documented here: Common mistakes with an observable collection
The author goes through several mistakes people make with them, including using them in the service layer.

Related

Dependency Injection vs Layered Architecture

I've been reading a lot about dependency injection and the service locator (anti-?) pattern - a lot of it on StackOverflow (thanks guys :). I have a question about how this pattern works when it's within a n-layer architecture.
I've seen a lot of blog posts where they describe injecting a IDataAccess component into the business objects. E.g.
public class Address
{
IDataAccess _dataAccess;
public Address(IDataAccess dataAccess)
{
this._dataAccess = dataAccess;
}
}
However, I was under the impression that in an n-layer architecture, the UI layer should not need to have any knowledge of the data access layer... or even know that there /is/ a data access layer! If DI requires exposing the IDataAccess interface in the constructors of the BusinessObjects, this then exposes to the UI the fact that the Business Layer uses a data access layer under the hood - something the UI doesn't need to know or care about surely?
So, my fundamental question is: Does DI require that I expose all my lower layer interfaces to all upper layers and is this a good or a bad thing?
Thanks
Edit: To clarify (after a few comments), I know my business object should be ignorant of the which specific implementation of which IDataAccess it uses (hence the Dependency being injected in the constructor) but I thought that the layers above the BO should not know that the Business Object even requires a dependency on a DAL.
This is really a fairly complex topic, and there are many ways of doing an n-tier architecture. No one way is "the right way", and how you do it depends on your needs as much as it does your personal preferences.
Dependency Injection is about managing dependencies. If your object should be unaware of any dependency, then you would not write your objet in the way you mentioned. You would instead have some other service or method that would populate the data in an agnostic way. Data doesn't mean "Database" either. So IDataAccess could mean it comes from a database, or it comes from a network socket or it comes from a file on disk. The whole point here is that Address does not choose what dependencies it creates. This is done through configuration at the composition root.
Things need data, otherwise your app is probably useless. Making your Address object load itself, however, may not be the best way to go about things. A better approach may be with a factory class or service method.
I think the answer is rather simple. Your bottom layers (interface, bll, dal, entities) are just a bunch of libraries. It is up to the client to decide which libraries to be used and it will increase client's flexibility. Moreover they are libraries, so any application-related configurations (connection strings, data caching, etc) lies on the client. Those configuration itself, sometimes also need to be injected and included into Composition Root.
However, if you want to has an uniform logic and not client's flexibility, you can choose web/app services as an additional layer.
1st Layer Entities
2nd Layer Interface
3rd Layer BLL & DAL
4th Layer Web/App Services
5th Layer UI
This way, your composition root exists in one layer (4th). And add your UI just need to add service reference to 4th layer (or 1st if needed). However, this implies the same Mark Seeman's article again, layering is worth the mapping. I assume that you can change the app/web service to Composition Root.
Moreover, this (app/web service) design has pros/cons. Pros:
Your app is encapsulated
Your app is being bridged by app/web services. It is guranteed that your UI don't know the DataAccess, thus fulfill your requirements.
Your app is secured
Simply said, having UI need to access app service is a huge gain in security aspect.
Access Portability
Now your app can be accessed everywhere. It can be connected by 3rd party app (other web) without has relying on dlls.
Cons:
Overhead cost during service call
Authentication, network connection, etc, will cause overhead during webservice call. I'm inexperienced for the performance impact but it should be enough for high traffic app.
Inflexibility of client
Client now need to access BLL/Services by using services instead of normal objects.
More Service for Different Type of Client
Now you need to provide more service than needed. Such as WebRequestRetriever, MobileRequestRetriever instead of accessing to a mere IRequestRetriever and let the composition root wire up the rest.
Apologize if this answer boarden the topic (just realized after finished).
IMHO:
It depends on who does the injection !-
It seems you need to/expect to have an MVC or MVP architecture to be in place, where a controller or Presenter does the job of translating the UI calls to business objects ,back and forth -
Creating concrete implementations of IDataAccess, Sending it to Address class.
So that the UI is totally unaware of who is providing the data it needs, and it provides you the expected scalability.
Thanks
Tarriq

Pulling out business logic from the data access layer

We are writing some support applications (rather small) to our ERP system.
Thus until now I am feeling that I am using the Data Access Layer for 2 roles: the business layer AND the data access one.
I am having trouble deciding what I have to move to a separate layer and if I need to. I have read somewhere that knowing when to make layer separation is wisdom and knowing the patterns is just knowledge. I have neither in adequate amounts.
So I need some help to determine what is what.
My current DAL deals with fetching the data and applying basic logic on them. For example there are methods like
GetProductAvailabilitybyItem
GetProductAvailabilitybyLot
etc.
If I needed to separate them what I would have to do?
One other matter that is in my head is that in order to normalize my DAL and make it return different entities every time (through one general get method) I would have to use DataTable as return type. Currently I am using things like List<PalletRecord> as return types.
I feel that my apps are so small that its hard (and maybe useless) to discriminate these 2 layers.
My basic need is to build something that can be consumed by multiple front-ends (web pages, WinForms, WPF, and so on).
Additional Example:
Lets talk some barcode. I need to check if a fetched lot record is valid or not. I am fetching the record in DAL and produce a method returning bool in business layer?
Then i can call the bool method from whatever presentation in order to check if a textbox contains a valid lot?
Is this the logic extremely simplified?
Based on your description, you should definitely separate both layers right now, when the application is still small. You might feel a BL is useless when you're just accessing and displaying data, but with time you'll find the need to modify, transform, or manipulate the data, like coordinate object creation from different tables, or update different tables in a single action from the user.
The example you provided helps to support this idea, although is quite simplified.
Pablo's answer does offer some good design ideas too: you should definitely use an ORM to simplify your DAL and keep it very thin. I've found NHibernate and Fluent make a very good job on this. You can use the BL to coordinate access using Data Access Objects.
Given that you are dealing with very small applications, why not just have an ORM provide all data-access for you and just worry about the business layer?
That way you don't have to worry about dealing with DataTable's, mapping data to objects and all that. Much faster development, and you would reduce the size of the codebase.
For example, NHibernate or Microsoft's Entity Framework
Now, if you will be providing data to external consumers (you are implementing a service), you may want to create a separate set of DTOs that go through the wire, instead of trying to send your actual model entities.
I am not a big fan of nTire architecture and have some good reasons for it.
Main objective for such an architecture are
Ability to work with different underlying database separation of
context - i.e. application design and business logic Uniformity and
confirmation of best patterns and practices.
However, while doing so, you also make some sacrifices such as give up provider specific optimizations etc.
My advise is, you can go with two layer architecture,i.e. Data access and business logic layer and GUI or presentation layer. It will still allow you to have a common code for different platforms and at the same time will save you from spaghetti code.

database access from multiple applications

I have a windows form application(c#) and an asp.NET web application which both access Sql Server database. I want to centralize the database access. Which metedologies should i follow? What is the common approach to this issue?
Writing DAL and Model Libraries and using them in both application?
Writing WCF service including DAL model and using this service with both applicaiton?
None of the above?
Can you give me any idea?
Thank you.
I would go with the WCF approach. Keep in mind that when (not if, when) you have to make changes that pertain to one app, but not the other (yet), you will have to account for that in the common layer, so using interfaces may make your life a little easier.
The cleanest way is to wrap the DB with a WCF services.
If you don't write large amounts of data in one go you can use a WCF Data Service; this directly wraps an Entity Framework model and you can configure access to tables and methods in various ways.
What you want is to have one place where the DB is accessed, so that if there is an issue, you can fix it in one location, for instance.
Furthermore, if you want to log all calls to a particular table, for instance, the only way to make sure that will be done is by centralizing all calls to the DB this way and not allow anybody direct access to the DB.
Wrap the service, then keep the connection string secret.
I think using the SOA approach is really better (WCF or WebServices with a DAL layer) because this way you don't need to publish your DAL dll with the Windows Forms exe. Then, all changes to your data model will automatically happens to your both UI clients.
Remember that this can cause its own problems:
Concern with security so that your Services cannot be accessed directly by URL, allowing someone to run your methods.
Concern about maintenance, because changes in data layer that needs to affect only one interface will be more difficult to control and needs to be better planned before (with the creation of new methods specific to certain intercace).
Decrease in performance, because the HTTP access is always more costly than direct communication with a dll.
Risk of lack of communication with the server, something that is expected to ASP.NET but requires additional concerns in the Windows Forms client to behave properly in these cases.
Option 1 seems simpler and I would do the same.
Option 2 with WCF will add additional code to your product and hence maintenance. Also this would mean an additional layer as well.
Corporate programmers like the second option (WCF service including DAL).

Designing an API: Use the Data Layer objects or copy/duplicate?

Struggling with this one today.
Rewriting a web-based application; I would like to do this in such a way that:
All transactions go through a web services API (something like http://api.myapplication.com) so that customers can work with their data the same way that we do / everything they can do through our provided web interface they can also do programmatically
A class library serves as a data layer (SQL + Entity Framework), for a couple of design reasons not related to this question
Problem is, if I choose not to expose the Entity Framework objects through the web service, it's a lot of work to re-create "API" versions of the Entity Framework objects and then write all the "proxy" code to copy properties back and forth.
What's the best practice here? Suck it up and create an API model class for each object, or just use the Entity Framework versions?
Any shortcuts here from those of you who have been down this road and dealt with versioning / backwards compatibility, other headaches?
Edit: After feedback, what makes more sense may be:
Data/Service Layer - DLL used by public web interface directly as well as the Web Services API
Web Services API - almost an exact replica of the Service Layer methods / objects, with API-specific objects and proxy code
I would NOT have the website post data through the web services interface for the API. That way leads to potential performance issues of your main website. Never mind that as soon as you deploy a breaking API change you have to redeploy the main website at the same time. There are reasons why you wouldn't want to be forced to do this.
Instead, your website AND web services should both communicate directly to the underlying business/data layer(s).
Next, don't expose the EF objects themselves. The web service interface should be cleaner than this. In other words it should try and simplify the act of working with your backend as much as possible. Will this require a fair amount of effort on your part? yes. However, it will pay dividends when you have to change the model slightly without impacting currently connected clients.
It depends on project complexity and how long you expect it to live. For small, short living projects you can share domain objects across all layer's. But if it's big project, and you expect it to exist, work well, and update for next 5 years....
In my current project (which is big), I first started with shared entities across all layers, then i discovered that I need separate entities for Presentation, and now (6 month's passed) I'm using separate classes for each layer (persistence, service, domain, presentation) and that's not because i'm paranoid or was following some rules, just I couldn't make all work with single set of classes across layers... Make you conclusions..
P.S. There are tools that can help you convert your objects, like Automapper and Value Injecter.
I would just buck up and create an API specifically aimed at the needs of the application. It doesn't make much sense to what amounts to exposing the whole DB layer. Just expose what needs to be exposed in order to make the app work, and nothing else.

How many entities should RIA domain service include?

I was wondering about how to exactly implement domain service in RIA. Is it common to include all entities in the entire domain model in a single domain service, thus making the service responsible for the entire database? Is this the way it's normally done? I really have no reason to separate data access into different services, but I was wondering if this is considered a good practice, and what the pros and cons of such an approach would be.
Also, is it considered a good or bad practice to register domain context as a singleton with IOC, so that the entire application works with the same set of data, thus avoiding concurrency issues and similar problems?
Thoughts?
Thank you
We have two separate services in our app: one for the data model and one strictly used for authentication. We took this design from MS's business sample app structure.
We considered breaking up our data domain service into smaller components but decided against it because it didn't seem to add any advantage (other than reducing service class size.) If you have distinct data models that are completely independent from each other then going that route might make sense. Intuitively the domain service should represent the entire domain. If your domains are independent (with the occasional need for crossover) then it makes logical sense to segregate them in that way.
Regarding using the context as a Singleton: I tried that and ended up creating class-scope instances instead. We haven't experienced any issues doing it this way as they all use the same underlying data connection. I don't know what the "official" best practice is, but this is the way I've seen it done in numerous RIA apps.
Thanks Nick. I actually did the same thing as you, I built two services, one for authentication and one for data access. That seems most logical to me.
As for making datacontext a singleton, I've tried that as well and it works nicely. No need to constantly reload and refresh data and worry about concurrency issues in other classes :)

Categories