I currently developing a client server application and use a WCF interface for communication.
Via this interface i get my business objects. I am using MVVM.
The users can make changes in the client (e.g. via a textbox). Later i want to send the obejcts back to the server and the server shall decide whether an object needs to be saved or whether it should ignore it because noch changes were made.
I am now looking for a way to "tag" the business objects so that the server can make his decision.
Has somboody an idea how i could do this???
Or much better does anyone know a tutorial???
What you're trying to do is already implemented in the Entity Framework Self Tracking Entities. I don't know if you are using EF in the backend as the ORM, though, you may use some code from the STE T4 Template to implement your own change tracking logic.
Related
I will start to develop an application that has to access to database. What kind of design patterns area usually need to be implemented to make my application more flexible for example changing DB client from SQL to Oracle.
I believe to perform execution of some query I can implement Template Method Pattern. And to get connection a singleton pattern with double check would be sufficient.
Is there anything else I should know before starting?
Application will be developed in C#, so there is support for object inheritance and polymorphism.
Any help is appreciated.
Make sure all your code is encapsulated in a data access layer. Code against interfaces so that if you need to write a new data access library, you don't have to change all calling code. This will at least isolate all data access into on library. How likely is the changing of database to be? Don't make the software complex for the what-ifs as this will just make life more difficult.
Abstract something 'on-fly' and only when You can clearly see a benefit.
Otherwise - that's just waste of time.
Do not think like:
I should use pattern [x] because it might fix [y]
Think like this:
Oh crap, again got to write same stuff. Let's see how we could avoid that...
There's a good design pattern called Data Access Object, you will have to incorporate it into C#.
Summary:
The DAO implements the access
mechanism required to work with the
data source. The data source could be
a persistent store like an RDBMS, an
external service like a B2B exchange,
a repository like an LDAP database, or
a business service accessed via CORBA
Internet Inter-ORB Protocol (IIOP) or
low-level sockets. The business
component that relies on the DAO uses
the simpler interface exposed by the
DAO for its clients. The DAO
completely hides the data source
implementation details from its
clients. Because the interface exposed
by the DAO to clients does not change
when the underlying data source
implementation changes, this pattern
allows the DAO to adapt to different
storage schemes without affecting its
clients or business components.
Essentially, the DAO acts as an
adapter between the component and the
data source.
Check the Catalog of Patterns of Enterprise Application Architecture by Martin Fowler.
You may find a few good ideas there.
you should investigate the user of the data mapper pattern to keep the implementation details of how your data is stored (SQL/Oracele/Access) independent from the use of the data itself.
http://martinfowler.com/eaaCatalog/dataMapper.html
Let me set up my LOB scenario.
I am re-writing our core business app. The requirements are that I create an internally usable app (I'd like to use Silverlight) that our employees use on a daily basis. I also need to provide a SOAP service that can be used to input orders, get invoices, etc.
I also will be doing this in pieces, so when I update a record in the new SQL Server database, I need to make sure to update our legacy SQL Server as well.
So, it certainly makes sense to create a DAL that will pull data from the new SQL server, as well as write back to 2 data stores.
It would also make sense to create a BLL that can be used by both Silverlight/RIA and the WCF web services.
I have created a data entity of the new database in it's own project and it is used in all the other projects. The problem here is that RIA seems to require that I create it right inside the ASP.Net project in order to get the metadata for Silverlight. Without this, I need to manually re-create the metadata for Silverlight to access it correctly.
My question then, should I create duplicates of the Entity Model? One for RIA and one for everything else? Is there a better way to do this? Should I just forego using RIA and have Silverlight access WCF services? Or should I just continue to duplicate the metadata in RIA?
We use entities for direct reference to storage and Data Transfer Objects (DTOs) which are almost identical for passing back/forth between BLL and WCF/GUI/etc. We map between the 2 using AutoMapper which means there's very little additional work but we don't have to worry about if a given entity is attached to the context/tracking state changes/etc...
Edit: You definitely want to keep your code as DRY as possible. Personally, I'd look at using DTOs above the BLL and either having 2 sets of repositories which are co-ordinated in the DAL (one RW, one W only). or even having Meta-repositories which handle the datasets on the 2 stores themselves.
If you're not already using it, Unity and IoC would be of real benefit to you here. You might also want to use one of the modular code patterns to allow you to register [n] data stores in different modes, so that when you finally want to retire the old store, you don't need to do much work.
I'd also question whether your entities need to be defined in ASP.Net - you may simple be able to reference the appropriate DLLs from your entity/DTO project and add the appropriate markup/config
I'm still pretty new to Silverlight, quite new to WCF, and am trying to broaden my horizons into both. I'd like to learn what is considered to be good practices while doing so.
On the client side, I have a Silverlight application. On the server side, I have a database that the Silverlight application will be utilizing. In between the two (okay, it's server-side, but...), I have a WCF service that the client calls upon to get the data from the database.
I have created a class that is marked as a DataContract and is used by the WCF service. That class is an object model populated with data from the database. On the client side, when it requests and receives an instance of this class, it uses the instance data to instantiate and populate a client-defined object that has additional client-defined members.
It's my use of the DataContract that most worries me. To create an instance of an object to be serialized and sent, only to be pillaged for its data so another object can be created seems...inefficient. But if it's considered a good practice I can get past that.
I did consider going the route of a web handler (.ashx) and using a proprietary binary standard to communicate the data, but I think going the WCF route may be more applicable and usable in the future (thinking: job).
I don't see any particular problem with your approach.
In my mind what you're describing is the transfer of data from service to client as a DTO (data-transfer object), and then using that DTO to populate a view model object. It is also quite common for the DTO and view model objects to use varying levels of granularity in terms of the data they represent (typically DTOs will be more coarse grained), and the view model will contain behaviour that is specific to the UI.
You might want to look at tools and frameworks that help in the mapping between DTOs and view model objects. One of my favourites is AutoMapper.
I have some trouble getting my head around how to implement more complex operations in a Domain Service in RIA Services. This is all Silverlight 4, VS 2010 and .Net Framework 4 in Beta 2.
Goal
I wish I could create an operation on my LinqToEntitiesDomainService that would have a signature something like this:
public UnwieldyOperationResult PerformUnwieldyOperation( UnwieldyOperationParameters p );
The idea is that this operation takes a colleciton of parameters and performs rather complex operations which would update different instances and types of the entities that are otherwise manipulated through the DomainService CRUD functionality.
Problem
The immediate problem i hit is that does not seem to be allowed to pass the custom type as parameter to the method, and I suppose something along those lines go for the return value. I want to encapsulate the operation parameters in a DTO for clarity, and this unwieldy operation does not have any corresponding entity in the legacy database that I have wrapped with Entity Framework 4.0 model, which I am in turn basing the Domain Service on.
Is a domain service supposed to deal with only the types that are entities in the underlying EF model? Is it not designed to expose more complex operations like my UnwieldyOperation?
If so, can I build another service somehow that allows both the operation signature and to manipulate the entity framework?
I have understood that only one Domain Service can handle an entity from the model. This has led me to cram all the CRUD and now also the UnwieldyOperation into one Domain Service, although my first idea was to split the service into smaller parts.
If I'd get the operation to work with parameters and return value in the Domain Service, my next wish would be to have the entities that are already loaded in the domain context at the client refresh themselves.
Is there any efficient mechanism for such a thing?
How would you go about to do that?
What I have so far...
In short, this is what I have so far:
I have wrapped an existing legacy database
with an Entity Framework 4.0 model with as
little extra padding/code as
possible. This means right-click, add and generate from database.
I have implemented the simpler CRUD operations in the DomainService and I am using them successfully to display and edit straight forward data. I have some encapsulation of logic through ViewModels in client but I expose the Entity classes directly, but I think this is unrelated to my problem/question.
I have realized that I can't add the UnwieldyOperation in an as straight forward manner as I initially thought... Also I suspect/hope that I have misunderstood some aspects of the Domain Service mechanism, which has led me to the current situation.
One way to go?
Writing this down in a question like this gives me the idea that perhaps I'd go in this direction:
LegacyModelService expose the CRUD operations as I have already done.
Expose the Unwieldy operations in another service. Should I make that a RIA Doamin Service or just plain WCF?
Access the Entity Framework model from the new UnwieldyOperationsService and manipulate the data layer there.
Explicitly reload or refresh the client domain context for the LegacyModelService at the client to reflect the changes that may have resultet from the UnwieldyOperation. What would be a good way get this done?
Check out http://msdn.microsoft.com/en-us/library/ee707373%28VS.91%29.aspx for naming conventions over and above simple CRUD, maybe Invoke or Named Update operations would be suitable?
We are trying to come up with an architecture approach for designing an application where front end runs as a browser based xaml app.
this app contacts services on the web server that are built using wcf, the wcf services host domain model that uses nhibernate for persistence (so it is hibernate aware by using interfaces for lists and sets and such)
i understand that when using soap web services, only schema are shared and not types, but we would like to share types since types would have methods, business logic etc ..
and since both ends of communication are in our control, we don't really need to use soap, but for all clarity and debugging, security and general peace of mind, SOAP is desired.
wondering what if this is an approach people use, and if there are any frameworks out there that enable/guide/ease the task of converting proxies back to their original types..
or if there are any other approaches possible.
Marc is correct that you cannot share types in an SOA architecture. In fact, in SOA, it is undesirable.
But you've decided you don't need SOA, so you can share types if you like. Just click the "Advanced" button when you use "Add Service Reference", and choose the set of types you want shared between the client and service.
Of course, this does bind your client and service tightly together, and loses other benefits of SOA, but it's no worse than if you were using COM.
You CANNOT share types (e.g. classes) in a true SOA world - because in the end, what it really comes down to is everything is serialized into a XML stream and sent across the wire. Also - one end could be .NET and the other end PHP or Java - now I don't think your Java client will understand and be able to execute .NET methods on your object.
SOA is a different beast than "object remoting" - it just doesn't lend itself to actually remoting objects across the wire - it sends XML messages across - that's all it can do. It can send data back and forth, but not code.
If in your scenario you do control both ends of the conversation, of course what is available to you is the ability to package all your business objects into a shared assembly (or several), and then physically share those assemblies between your server and client. In this case, you could serialize an object "Customer" on the server, send the XML message across, and on the client side, deserialize it into a "Customer" again. But be aware : all you're sending across is the state of Customer - the values in its fields and properties. You're not really sending the code across - that just happens to be available on both ends of the wire.
What a lot of folks do in this case is extracting the information of interest from the actual "Customer" object into a "Data-Transfer Object" often called "CustomerDTO", by using e.g. something like AutoMapper in order to make it easier, and then they create a new Customer instance on the other end of the wire and copy the data back from the DTO into the "real" object.
Marc
There is an easy way to share types between client and service, just by adding reference to shared type assembly to your client BEFORE adding the service reference.
You can find the detailed scenario and sample project there:
http://blog.walteralmeida.com/2010/08/wcf-tips-and-tricks-share-types-between-server-and-client.html