static DataServiceContext in a static class - c#

I'm new to EF and it appears that I have made a mistake with it but I would like clarification.
My scenario:
Winforms App (ClickOnce)
A static class whose only responsibility is to update the DB via a DataServiceContext - single URI
Only one control in the entire application uses this class
With the static class I created a single readonly instance of a DataServiceContext. There is also a GetMethod which gets the data using a ToList() on the context - this list is then used for data binding. I just need simple CRUD so there is a Save/Delete method, entities are passed in and updated.
As I've read a bit more about EF I understand that shared contexts are bad due to issues with concurrency. It seems that I would get away with a static context in this scenario as there would only ever be a single user accessing the same context per application instance or would I? I want to keep things as simple as possible. I'm starting to think perhaps I should turn the static class into a regular class with an immutable DataServiceContext instance shared between methods as a safeguard? Perhaps I should apply a using(DataServiceContext) within each method that makes a service call via SaveChanges to tighten things up even more? Do I need to do these things now or might it be YAGNI?
As I'm self taught here (no mentors), I might be in danger of going AWOL. I probably need some ground rules about EF my current reading as not led me to as yet. Please help.

This isn't just about concurrency (but yes: that is an important concern) - it is also about correctness. If you have a single data-context, there are a few issues:
Firstly, memory: it will slowly grow over the life of the application, as more data is attached into the identity manager and change tracker.
Secondly - freshness: once things are attached to the data-context, you'll see the in-memory object - it may stop showing the up-to-date state of objects in the database
Thirdly - corruption: if anything goes wrong, the noral way of handling that is to simply rollback any in-flight changes, discard the data-context and report the error and/or retry the operation (on a fresh data-context); you can't keep using the old data-context - it is now in an undefined state
For all of these reasons, the general pattern is that you use a data-context only as a unit-of-work, to perform a single operation or a set of related / scoped operations. After that, burn it and start again.

Related

Mediatr - Where is the right place to invalidate/update cache

This question stems from this other question I had asked about too many interfaces, QCRS and Mediatr library (request/response)
Mediatr: reducing number of DI'ed objects
I have created bunch of commands and queries and I have bunch of behaviors and one of them being is a Cache behaviour that for every query, cache is checked for the value before the query is actually executed against the db. So far this is working great, but the delima comes in when I have an UpdateSomethingCommand, once I update the underlying object in the db, I would like to refresh the cache with what was successfully saved to the db.
My question is specifically when to actually update the cache:
In the UpdateSomethingCommandHandler (this might be breaking the SOLID principal)
Call another command in UpdateSomethingCommandHanlder that is specifically designed to update caches (not sure this is a good design principal)
Introduce another behavior that is specifically designed for updating caches (not sure how to go about this yet)
Is there a better solution?
We had a similar need on a project that uses MediatR and ended up incorporating caching into the mediator pipeline, including cache invalidation as you describe.
The basic premise is that we have two different behaviors inserted into the pipeline, one for caching a response from a request, and one for invalidating a cached request response from a different request.
There is a little bit of interplay between the two behaviors in the fact that they need to exchange a cache key in order to invalidate the correct request.
I've recently pulled some of this work into a stand-alone library that in theory can be dropped in as-is to any project using MediatR. In your case, you may just want to look at the techniques we've used here and recreate them as needed.
Rather than repeat everything here and now, I'll point you at the project page where there is some documentation under the Getting Started link on the homepage:
https://github.com/Imprise/Imprise.MediatR.Extensions.Caching
In my opinion, the cache invalidation makes the whole process extremely simple and straightforward, but there are cases where we needed finer control over when the invalidation occurs. In these cases the other approach we have taken is to inject an ICache<TRequest, TResponse> cache into INotificationHandlers and then call _cache.Remove(key); manually as needed. Then, from any requests you know should invalidate just raise a notification that is handled by the INotificationHandler e.g. _mediator.Publish(SomethingUpdated);
My suggestion is to use a cache behavior that acts on requests that implement some sort of ICacheableRequest marker interface and invalidating the cache as a step in the corresponding Update/Delete command handlers (like you mentioned in point 1).
If you choose to create an invalidator behavior there are a few problems.
First, it's unclear that the command is invalidating the cache. Whenever I need to check what's going on when an entity is updated/deleted, I just follow the command handler, there are no side effects (harder to follow) by creating a separate cache invalidator.
Second, even if putting the invalidation code in a separate file follows better the SRP, you will have to choose where to put the cache invalidator class. Does it go next to the cached query or next to the command handler that invalidates the cache?
Third, in many scenarios you won't have enough information about the key used to cache the request in the associated command, you'll only get that and any other extra invalidation condition in the CommandHandler.

Static Class Persistance in MVC Applications

I have over the last couple of months migrated my Webforms knowledge to MVC knowledge, and I have to say that after originally being an MVC skeptic I am loving MVC and the way it works.
The only thing I am still a bit unclear about is how static classes are persisted in MVC. In Webforms static class values were shared amongst the different clients accessing the application, which could lead to a user overwriting another users values should you decide to use static classes to save user related variables.
My first question is whether or not this is still the case in MVC?
Then my second question is about where to keep the DBContext instance in my MVC application. Currently I have it as a public variable in a static DAL class. The single context is then shared amongst all the clients.
The more I read about this the more I am starting to believe that this is the incorrect approach, but recreating the context inside each controller seems repetitive.
Is there a downside to having the Context in a static class?
The context is supposed to be short-lived, so it might seem repetitive, but yes, create a context inside each controller. Use a single context per request to be precise.
Persisting a single DbContext instance across the lifetime of an application doesn't sound like a good idea to me. I usually use one DbContext instance per Request.
Following are 2 points that you might want to consider while deciding the appropriate lifetime for DbContext in your application:
Re-using the same context for multiple Requests lets you benefit from
the Cached entities and you could save many hits to the Database but
you might then run into performance issues because you could end up
having all your Database entities in memory at some time.
Re-instantiating context too often on the other hand is also not
recommended because it is an expensive operation.
You have to find a balance somewhere between these 2 approaches and for me, instantiating DbContext Per Request works best in most scenarios.
The DbConext is not thread safe, EF allows only one concurrtent operation on the same context. Therefore it is not a good idea to share it across requests.
In the most cases a context per request is the best solution. (Hint: There are some IoC frameworks like autofac whichcan create instances per request)

Best way to store data (single object) in Web API project without database

My project group and I are to develop a generic workflow system, and have decided to implement a single Node (a task in the workflow) as a C# Visual Studio Web API project (Using the ASP.NET MVC structure).
In the process of implementing a Node's logic, we've come across the trouble of how to store data in our Node. Our Node specifically consists of a few lists of Uri's leading to other Nodes as well as some status/state boolean values. These values are currently stored in a regular class but with all the values as internal static fields.
We're wondering if there's a better way to do this? Particularly, as we'd like to later apply a locking-mechanism, it'd be prefereable to have an object that we can interact with, however we are unsure of how we can access this "common" object in various Controllers - or rather in a single controller, which takes on the HTTP requests that we receive for ou Node.
Is there a way to make the Controller class use a modified constructor which takes this object? And if so, the next step: Where can we provide that the Controller will receive the object in this constructor? There appears to be no code which instantiates Web API controllers.
Accessing static fiels in some class seems to do the trick, data-wise, but it forces us to implement our own locking-mechanism using a boolean value or similar, instead of simply being able to lock the object when it is altered.
If I am not making any sense, do tell. Any answers that might help are welcome! Thanks!
Based on your comments, I would say the persistence mechanism you are after is probably one of the server-side caching options (System.Runtime.Caching or System.Web.Caching).
System.Runtime.Caching is the newer of the 2 technologies and provides the an abstract ObjectCache type that could potentially be extended to be file-based. Alternatively, there is a built-in MemoryCache type.
Unlike a static method, caches will persist state for all users based on a timeout (either fixed or rolling), and can potentially have cache dependencies that will cause the cache to be immediately invalidated. The general idea is to reload the data from a store (file or database) after the cache expires. The cache protects the store from being hit by every request - the store is only hit after the timeout is reached or the cache is otherwise invalidated.
In addition, you can specify that items are "Not Removable", which will make them survive when an application pool is restarted.
More info: http://bartwullems.blogspot.com/2011/02/caching-in-net-4.html

C# reference collection for storing reference types

I like to implement a collection (something like List<T>) which would hold all my objects that I have created in the entire life span of my application as if its an array of pointers in C++. The idea is that when my process starts I can use a central factory to create all objects and then periodically validate/invalidate their state. Basically I want to make sure that my process only deals with valid instances and I don't re-fetch information I already fetched from the database. So all my objects will basically be in one place - my collection. A cool thing I can do with this is avoid database calls to get data from the database if I already got it (even if I updated it after retrieval its still up-to-date if of course some other process didn't update it but that a different concern). I don't want to be calling new Customer("James Thomas"); again if I initted James Thomas already sometime in the past. Currently I will end up with multiple copies of the same object across the appdomain - some out of sync other in sync and even though I deal with this using timestamp field on the MSSQL server I'd like to keep only one copy per customer in my appdomain (if possible process would be better).
I can't use regular collections like List or ArrayList for example because I cannot pass parameters by their real local reference to the their existing Add() methods where I'm creating them using ref so that's not to good I think. So how can this be implemented/can it be implemented at all ? A 'linked list' type of class with all methods working with ref & out params is what I'm thinking now but it may get ugly pretty quickly. Is there another way to implement such collection like RefList<T>.Add(ref T obj)?
So bottom line is: I don't want re-create an object if I've already created it before during the entire application life unless I decide to re-create it explicitly (maybe its out-of-date or something so I have to fetch it again from the db). Is there alternatives maybe ?
The easiest way to do what you're trying to accomplish is to create a wrapper that holds on to the list. This wrapper will have an add method which takes in a ref. In the add it looks up the value in the list and creates it when it can't find the value. Or a Cache
But... this statement would make me worry.
I don't want re-create an object if
I've already created it before during
the entire application life
But as Raymond Chen points out that A cache with a bad policy is another name for a memory leak. What you've described is a cache with no policy
To fix this you should consider using for a non-web app either System.Runtime.Caching for 4.0 or for 3.5 and earlier the Enterprise Library Caching Block. If this is a Web App then you can use the System.Web.Caching. Or if you must roll your own at least get a sensible policy in place.
All of this of course assumes that your database's caching is insufficient.
Using Ioc will save you many many many bugs, and make your application easier to test and your modules will be less coupled.
Ioc performance are pretty good.
I recommend you to use the implementation of Castle project
http://stw.castleproject.org/Windsor.MainPage.ashx
maybe you'll need a day to learn it, but it's great.

What are the pros/cons of choosing between static and instance data access classes in a web app?

I've read several other questions on this topic (here, here, and here), but have yet to see a great answer. I've developed my fair share of data access layers before and personally prefer to use instance classes instead of static classes. However, it is more of a personal preference (I like to test my business objects, and this approach makes mocking out the DAL easier). I have used static classes to access the database before, but I've always felt a little insecure in the appropriateness of such a design (especially in an ASP.NET environment).
Can anyone provide some good pros/cons with regards to these two approaches to developing data access classes with ADO.NET providers (no ORM), in an ASP.NET application in particular. Feel free to chime in if you have some more general static vs. instance class tips as well.
In particular, the issues I'm concerned about are:
Threading & concurrency
Scalability
Performance
Any other unknowns
Thanks!
Static based approaches really typically have one, and only one, main advantage: they're easy to implement.
Instance based approaches win for:
Threading and Concurrency - You don't need any/as much synchronization, so you get better throughput
Scalability - Same issues as above
Perf. - Same issues as above
Testability - This is much easier to test, since mocking out an instance is easy, and testing static classes is troublesome
Static approaches can win on:
Memory - You only have one instance, so lower footprint
Consistency/Sharing - It's easy to keep a single instance consistent with itself.
In general, I feel that instance-based approaches are superior. This becomes more important if you're going to scale up beyond a single server, too, since the static approach will "break" as soon as you start instancing it on multiple machines...
My general feeling is: Why instantiate if you don't have to?
I use static classes when there wont be any use for multiple instances and there isn't a need for instance members. As for the DAL, the point is that there is only one. Why instantiate it if there is no value in it?
Look at this link, which shows that static method calls are faster than instance class method calls.
This link shows that an advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added.
This link shows that a static class can be used as a convenient container for sets of methods that just operate on input parameters and do not have to get or set any internal instance fields. For a DAL, this is exactly what you have. There is no reason to create any internal instance fields, and therefore, no reason to instantiate.
I have been using a static DAL for years, and I agree with your concerns. Threading and concurrency is the most challenging and in my case I store different connection objects in thread static structures. It has proven to be very scalable and performs well, even more so now that I am converting PropertyInfo into PropertyDescriptor which gives me the same benefits of reflection with better performance. In my DAL I simply have to write:
List<Entity> tableRows = SQL.Read(new SearchCriteria(), new Table());
Everything spawns off the SQL static class, and that makes my code a lot simpler.
For me the main reason is that I don't need to keep the state of that DAL object. The state of the objects it uses don't span the scope of the method they are embeded. This way why would you keep multiple instances of an object, if they are all the same?
With the latest versions of the ADO.NET, seems to be best practice to create and destroy the connection to the database within the scope of your call, and let the ConnectionPool take care of the whole connection reusability issue anyway.
Again with the latest versions of the .NET Framework, TransactionScope (which would be one reason to manage your connections yourself) move up to the business level, which allow you to join multiple calls to the DAL within the same Scope.
So I can't see a compeling case to create and destroy (or cache) instances of the DAL.

Categories