Okay, so I have this Silverlight client program. I'm not allowed to use the web project, but I do need to be able to read from an SQL database for my data.
Some internet searching brought me to LINQ to SQL and the System.Data.Linq.DataContext object, as well as SQLMetal.exe. I have created my data context object from the meta data in a remote SQL database and the code looks okay (from what I can tell - all the right names and types seem to be there).
What I wanted to do was add this into Silverlight, but I realised, on importing the code, that you can't use System.Data in a Silverlight application, which sort of rules out having this code in the Silverlight client itself. Now this is annoying because a DataContext quite conveniently comes with properties which are tables and such like (I find those really convenient in Silverlight).
So I can't do it the 'normal way'. I can do it with a WCF service, but... well, here's where I could use some advice. I can create a WCF service with asynch calls, but I'm not really sure in what way to wire up the DataContext object. I mean... I need access to the classes in there within my Silverlight application (for my entities in the database) (and I'm not quite sure how to do that - help there would be appreciated). Then to synchronise it all up? Well, I could use some suggestions. For example, before, I have an exposed ObservableCollection. In its getter, it repopulated itself with the contents of, for example, Context.Customers. This made things nice and easy, but I can't see a way of doing something like that now. If I made a call to an asynch service for every 'get', surely this would be unacceptably slow.
If you could help me pick my way through this, I would be grateful. Thanks.
You definitely need to read about Entity Framewrok and couple articles about using WCF RIA + EF in Silverlight applications.
Hope, that will help you.
As mentioned above, you can use RIA services.
But more importantly... you should never use the classes that are generated in LINQ to SQL or EF in your client application. Your client application should only know about and use Domain Layer objects. Your datacontext and the types it uses should stay buried behind a repository pattern that gives you back Domain types.
Your client, whatever that may be (Silverlight app, WPF app, etc) only needs to (and should only) use these domain types. This is part of the whole separation of concerns and SOLID principles. Because I can guarantee you at some point in the lifecycle of the app you will swap out your source for data, so you may end up using Entity Framework, or NHibernate to talk to the db instead, in that case your client would be hard-wired to your LINQtoSQL types, and you wouldn't be able to swap out the ORM layer without breaking the client.
Related
MS stack developer historically.
I have committed to retooling to the following stack
angular -> ms web.api2 -> C# business objects -> sql server
Being old, I develop the database from requirements and use Codesmith to generate the business logic layer. (yes, I have heard of entity framework. even tried it once).
As I embrace Angular and web API 2
I find that Angular wants me to write a model on the front end. This seems to be just a data structure, I cant even add helper methods to it
So I also often write a class with helper methods that takes an instance of the model. Kind of ugly,but it does marry structure and logic.
I find that Web API2 wants me to write a model. This again seems to be just a data structure. I am exploring the dynamic data type, but really this doesn't buy me much. Instead of writing a class, I'm writing a mapping function.
The question is this:
Is there any way around having 3+ copies of each class spread across the stack?
Codesmith is a very capable code generator... it can gen multiple files... but...
If its just a couple data members, and 3 places, I can copy paste edit and get it done.
Just seems to me that now committing to keeping a data structure in synch in 3 different environments is setting oneself up for a lot of work.
I have spent the last 15 years trying to shove as much code as I can into a framework of inheritable classes so I can keep things DRY.
Am I missing something? Are there any patterns that can be suggested?
[I know this isn't a question tailored for SO, but it is where all the smart people shop. Downvote me if you feel honor bound to do so.]
Not entirely familiar with how CodeSmith generates it's classes, but if they are just plain-old-CLR-objects that serialize nicely, you can have WebApi return them directly to your Angular application. There are purists that will frown upon this, but depending on the application, there may be a justification.
Then, in the world of Angular, you have a few options, again, depending on your requirements/justification, and your application - again, purists will definitely frown upon some of the options.
create classes that match what's coming down from the server (more correct method)
Treat everything as "any", lose type safety, and just access properties as you need them i.e. don't create the model. (obviously less correct method)
find a code generation tool that will explore API end points to determine what they return, and generate your typescript classes for you.
Personally, using Entity Framework, I (manually) create my POCO's for database interraction, have a "view"/DTO class that WebAPI would then send back to the client, and a definition of the object in Typescript, but I am a control freak, and don't like generated code.
I have been tasked with moving all SqlDataSource objects out of an ASP.NET pages aspx files and putting them into a separate class file but am lost. Is there a way to create a SqlDataSource object in a separate class and assign query strings to the SelectCommand, DeleteParameters, InsertParameters, etc?
To where you can call the object on a separate page rather than have the code in the aspx?
Yes, you can do that. I would recommend that you move all the database IO to a web service.
I also want to add that this is a very good step that you are taking, as far as the security of your application. Separating your data access from your user IO like this is something I consider to be a must-have security measure. Done right, you will bump up the security of your application significantly.
You can create a WCF web service easily enough. There are plenty of tutorials on the web, and I'll be happy to give you pointers as you go along. The web service would have CRUD (insert, select, update, delete) operations. You can then create an "Object" type datasource on the web page, that points to your web service, and the elements on the page can get their data from those object datasources. You can also instantiate the web service in your code behind, and use it to manipulate the data. When you create the object type data sources, you will specify the service methods that correspond to each of the commands (select, insert, update...). Hope this points you in the right direction, and feel free to ask me more in the comments, or you can initiate a chat and I will give you my email where you can holler at me.
As already mentioned, it is possible to move the SqlDataSource controls out of the WebForm. I'll assume for the moment that your current code declares these controls in the .aspx file. You could change to an imperative approach, for example, and instantiate the datasource controls in an event handler of a WebForm's code-behind class, but you don't gain much by doing so. Indeed, you could even move a lot of the code that does the instantiation into a helper class that is called by the code-behind class, but this doesn't get you much further.
The original intent of the DataSource controls was to provide developers with a way to create rapid prototypes / proofs of concept. But these controls aren't really meant for production systems. They are a violation of the separation of concerns and make unit testing difficult, if not impossible.
In some ways, the DataSource controls can be easier to work with (say, in conjunction with a GridView control). But, this convenience comes at a price, which probably helps explain (in part) why you're being asked to do something with the controls. It's unfortunate that at when ASP.Net 2.0 (WebForms) was released in 2005, the literature that was published at the time heavily promoted the use of these DataSource controls. The community has learned since then that the production value of these controls is questionable, unless you are working on simple systems that don't need to evolve much over time.
As was mentioned by Anon316, you could use a web service to handle the CRUD operations. However, this solution might not be what you really need. Additional overhead is incurred by using a web service (i.e., additional HTTP requests to the service). Having your application make direct calls to the database can still be a very good approach.
With that said, consider creating a separate class (or classes) that provide data access facilities (e.g., a Repository). Entity Framework, for example, makes creating this kind of thing fairly straightforward (and there are many other data access libraries available in the .Net ecosystem). Be prepared for adding more code to the code-behind classes of your WebForms in order to make them interact with your Repository (or other Data Access) class(es). The benefit you'll gain is more testability and reuse of your data access code. Consider putting your data access class(es) into a separate project in your solution (to start).
Whether you create separate data access class(es) in your solution or a web service, you still have significant refactoring to do in order to move away from the DataSource controls. So, again, be mindful of the additional overhead involved in using a web service, recognizing that a web service tends to make sense when you have multiple clients (e.g. web and mobile), not when you only have one.
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.
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).
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.