Can repository class be scoped as singleton in ASP.NET - c#

I am trying to understand the scope of repository class in ASP.NET application. I assume they are thread safe in request scope since each request runs on a seperate thread. But how about having it singleton, is it a valid scenario.
Because these classes doesn't have state but only methods which manipulate data, so different threads executing these methods might be having different stack frames. Is my understanding right, could anyone provide more insights.
interface ICustomerRepository
{
List<Customers> GetAll();
Customer GetById(int id);
}
public class Customer : ICustomerRepository
{
//implement methods
}

Exposing a repository as a singleton for a concurrent environment is a bad idea.
You could possibly implement interface repository in a way that is safe to be used concurrently but this means that the only guarantee of concurrency consistency lies somewhere in the implementation. There is no other mechanism to enforce that concurrent calls would not fail, the contract at the programming language level (repository interface) is just too weak to express such requirement.
On the other hand, if each http context gets its own instance, the implementation details do not matter.
I suggest you read more on object lifetime. A singleton is just a specific example of a more general idea of controlling the lifetime. You can have objects with transient lifetime, objects that are shared in a single instance for the lifetime of you application but also objects that live in a context of a thread or an http context (that possibly spans multiple threads). And one of ways to control the lifetime is to have a factory that creates instances.
If you need something simple, you could have something that looks like a singleton but controls the lifetime in an arbitrary way:
http://netpl.blogspot.com/2010/12/container-based-pseudosingletons-in.html

Related

Pitfalls when sharing IDbConnection in ServiceStack

I have a service that use several repositories. I want them all to use the same transaction so that, if anything goes wrong, I can rollback the transactions and nothing is left in an invalid state in the database.
I've created a connection factory that returns the same connection to all clients.
public IDbConnection Connection => _db ?? (_db = _factory.OpenDbConnection());
Repositories takes the class holding this property as a constructor argument. This seemingly works, and enables them to use the same connection, and I can manage the transaction on the outer level. Both the connection factory and its clients are registered in IoC with ReuseScope.Request.
I am wondering though, are there any pitfalls to this?
What happens if someone™ starts using async/await with this shared connection? Do I have to ensure that the connection is never shared across threads? (I was thinking about storing it in a ThreadLocal inside the connection factory).
Anything else?
I'm sorry for this kind of vague question, but I believe this must be a quite common use case.
ADO.NET's IDbConnection resource instance is not thread safe and should never be used in multiple threads. Typically each Thread would retrieve its own pooled DB Connection from the Db connection factory.
Whilst async/await can continue on a different thread, they're not executed concurrently so the same DB Connection can be used as it doesn't get used by multiple threads at the same time.
When I do use repositories they would be responsible for logical units of functionality, (never per-table which I consider an anti-pattern forcing unnecessary friction and abstraction penalties), so I'd rarely have transactions spanning multiple repositories, if I did I'd make it explicit and pass the same DB connection to each repository within an explicit DB transaction scope, e.g:
public object Any(MyRequest request)
{
using (var dbTrans = Db.OpenTransaction())
{
MyRepository1.Something(Db, request.Id);
MyRepository2.Something(Db, request.Id);
//....
dbTrans.Commit();
}
}

ASP.NET Core pipeline multithreading

Does ASP.NET Core pipeline handle requests by multithreading?
If it does, how do you configure the number of threads? And also, should singleton services be thread safe?
The first question was already answered in the comment above (look into KestrelServerOptions)
Regarding thread safetly, the answer is in the documentation:
Singleton lifetime services are created the first time they are requested (or when ConfigureServices is run if you specify an instance there) and then every subsequent request will use the same instance. If your application requires singleton behavior, allowing the services container to manage the service's lifetime is recommended instead of implementing the singleton design pattern and managing your object's lifetime in the class yourself.
That means all requests for the service pull the same object, which means no per-thread objects, and thus no thread safety.
Thread safety
Singleton services need to be thread safe. If a singleton service has a dependency on a transient service, the transient service may also need to be thread safe depending how it’s used by the singleton.
Coudn't be more clear. Since the objects are not created per thread, they are not thread safe by default (though it's possible some services are designed to be).

C# Entity Framework: Singleton Context Pattern with MVVM

I've built a WPF application using Entity Framework. My data store consists of hierarchical data (one project, with multiple different children entities).
To date I've been using a singleton pattern for my Context, as this allows me to have a global navigation tree in my UI (which then lazy loads as the user chooses to expand a specific parent to show its children). This has been working great up until now, but I'm now running into the dreaded exception:
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
I understand that I'm seeing this exception due to some actions being performed on some entities and simultaneous requests being made to load other entities, all from the same singleton context.
I further understand that it's best practice to keep a context as short-lived as possible. However, how will this be possible if I want the user to be able to see the whole project and make changes to some entities at a time? I'm at a complete loss as to how to have this global navigation tree in place with a short-lived context (as I keep running into the 'context has been disposed' problem).
Should I implement some locking mechanism around the context, or worse still, have this locking mechanism check each property before requesting it from the context? What is the recommended best practice for this scenario?
Correct, DbContext instances are cheap (they're just wrappers around pooled database connections).
If you want to maintain entities between persistence operations then you can detach and reattach entities to the new DbContext instance:
See https://msdn.microsoft.com/en-us/data/jj592676.aspx
FooEntity fromPreviousContext = ...
using (DbContext context = new DbContext())
{
context.Foos.Attach( fromPreviousContext );
context.SaveChanges();
}
A side-note: generally the Singleton pattern is considered by many to be an anti-pattern as it is easy to be misused especially when a singleton instance is being used to store contextual data - it becomes just a slightly more polite approach to global-variables. You might want to consider the Context pattern instead (unrelated to DbContext).

constructor injection & Factories: Object required in two types of life times?

I have a situation where I have an object C that is required by two types of classes. One of these class runs in separate thread, the other one creates multiple threads with the help of timer elapsed event.
So there are basically two life times of object C.
Object C is created along with A and B by a factory. For class1 I create the instance through master factory, but for second one I will have to pass the entire factory. The second class will now decide in run time (based on timer tick) how to create object C.
My question is regarding the second case: I am passing the entire factory, which besides the knowledge of creating object C also has a knowledge of creating A and B, is this considered bad design?
I am attaching a snapshot of what I am doing
Composition Snapshot
When working with multiple threads, each thread should get its own object graph. This means that every time you spin off some operation to a new thread (or a thread from the thread pool), you should ask the container again for the root object to work with. Prevent passing services from on thread to the other, because this scatters the knowledge about the thread-safety of your services throughout the code base, while with dependency injection you try to centralize this knowledge to a single place (the composition root). When this knowledge is scattered throughout the application, it becomes much harder to change the behavior of components what thread-safety is concerned.
When you do this, there is probably no need to even have two different configurations for that class. That class might simply be registeres as transient and because you resolve it at each pulse of the timer, each thread gets its own instance or the lifetime is scoped, in that case the class' lifetime will probably end when the timed operation ends.
The code that the timer calls and calls back into the container should be part of the composition root. Since the service is resolved on a background thread, you will often have to wrap that call in some sort of scope (lifetime scope, child container, etc). This allows that instance (or any other registered service) to live for the duration of that scope.

Do I need to dispose a web service reference in ASP.NET?

Does the garbage collector clean up web service references or do I need to call dispose on the service reference after I'm finished calling whatever method I call?
Instead of worrying about disposing your web services, you could keep only a single instance of each web service, using a singleton pattern. Web services are stateless, so they can safely be shared between connections and threads on a web server.
Here is an example of a Web Service class you can use to hold references to your web service instances. This singleton is lazy and thread-safe. It is advised that if you make your singletons lazy, they are also kept thread safe by following the same logic. To learn more about how to do this, read the C# In Depth article on Implementing Singletons.
Also keep in mind that you may run into issues with WCF web services. I'd recommend reading up on WCF's instance management techniques article, specifically the singleton section, for more details.
public static class WS
{
private static object sync = new object();
private static MyWebService _MyWebServiceInstance;
public static MyWebService MyWebServiceInstance
{
get
{
if (_MyWebServiceInstance == null)
{
lock (sync)
{
if (_MyWebServiceInstance == null)
{
_MyWebServiceInstance= new MyWebService();
}
}
}
return _MyWebServiceInstance;
}
}
}
And then when you need to access your web service, you can do this:
WS.MyWebServiceInstance.MyMethod(...)
or
var ws = WS.MyWebServiceInstance;
ws.MyMethod(...)
I've successfully used this pattern on several projects and it has worked well, but as tvanfosson mentions in the comments below, an even better strategy would be to use a DI framework to manage your web service instances.
I think the DataService inherits Dispose from Component.
Objects that implement IDispose should be disposed of manually to assist the garbage collector.
If you object is short lived use a using block. For objects that can be retained ensure that they object that retains them disposes of them when it is also disposed.
what are you trying to accomplish here?
If your worried about performance, then I would worry more about the responsiveness of the server hosting the webservice and the network speed, as they can dramatically affect the length of time you have to wait for the webservice call to complete (unless its asynchronous).
The examples on MSDN dont call 'Dispose' and its quite obvious that the garbage collector will do its job, so unless your working on a realtime system that needs to process over 100,000 records in memory every second, then maybe you dont need to come up with a way to dispose resources or manage memory.
I think the concerns of Seabizkit in the above answer are very legitimate.
It's quoted here:
#DanHerbert what happens when two threads call the singleton.. let me explain... there is a lock on the object.. to make it thread safe. Does that mean that if theard1 call accesses webInstance, then thread2 will wait on thread1 to finish. or is the lock purely for the creatation of the instance. say you have 10 callers.... does the lock mean they are chained... or async, i think you will get what I'm asking let me know if it wasn't clear. – Seabizkit Oct 13 '16 at 10:01
<
After I've done some testing I can tell that you won't be able to get any good performance when a single 'client' object is used by multiple different threads.
If ten threads are created and they all are using the same singleton 'client' then they will have to wait in line until all previous calls are done.
To see the proof for that please read and run a sample in this c-sharp corner article here:
https://www.c-sharpcorner.com/article/increase-performance-with-an-object-pool-or-why-singleton-may-cause-performance/
titled "Increase Performance with an Object Pool or Why Singleton May Cause Performance Issues".
Sorry to burst the bubble of the singleton web service users. Also, you would be very hard-pressed to find Microsoft's example where the web service client is "caged" in the singleton.

Categories

Resources