I am new to Linq to sql. And my question is simple.
Is it a good idea to have DataContext as public static member in DAL to act as singleton?
It is not really good idea to keep DataContext as singleton, for small application, you might not see any consequences, but if your web application which has many users to access, it will lead to memory leak. Why?
DataContext basically implements Unit Of Work behind the scene which has internal cache inside to track changes of entities and avoid round trip to database in one business transaction. Keeping DataContext for long time as static, it means internal cache will be increasing for the time being and is not released properly.
DataContext should be kept in one business transaction and release as soon as possible. Best practice for web application is to keep DataContext as per request. You are also able to make use of IoC Container, most of IoC Container support this.
I have also experienced one thing while using shared datacontext in DAL. Suppose there are two users A and B. If User A starts and transaction then user B can commit changes made by user A which is a side effect of using static DataContext.
I generally try to group functionality together for a Data Access class and make that class IDisposable.
Then you Create your DataContext in your constructor and in your dispose method you run your .dispose() call on the DataContext.
So then when you need something from that class you can wrap it in a using statement, and make a bunch of calls all using the same DataContext.
It's pretty much the same effect as using a Static DataContext, but means you don't forget to close down the connection, and it seems a bit more OO than making things static.
public class MyDataAccessClass: IDisposable
{
private readonly DbDataContext _dbContext;
public MyDataAccessClass()
{
_dbContext = new DbDataContext ();
}
public void Dispose()
{
_dbContext.Dispose();
}
public List<CoolData> GetStuff()
{
var d = _dbContext.CallStuff();
return d;
}
}
Then in your class
using(var d = new MyDataAccessClass())
{
//Make lots of calls to different methods of d here and you'll reuse your DataContext
}
I recommend you to read about 'unit of work' pattern. I.e. http://stuartharris4.blogspot.com/2008/06/working-together-linq-to-sql.html
You most definitely should not have a static DataContext in a multi-threaded application such as ASP.NET. The MSDN documentation for DataContext states that:
Any instance members are not guaranteed to be thread safe.
Related
I have this base class for all my unit tests that spins up an in-memory database
public abstract class TestWithSqlite : IDisposable
{
private const string InMemoryConnectionString = "DataSource=:memory:";
private readonly SqliteConnection _connection;
protected readonly ToDoDbContext DbContext;
protected TestWithSqlite()
{
_connection = new SqliteConnection(InMemoryConnectionString);
_connection.Open();
var options = new DbContextOptionsBuilder<ToDoDbContext>()
.UseSqlite(_connection)
.Options;
DbContext = new ToDoDbContext(options);
DbContext.Database.EnsureCreated();
}
public void Dispose()
{
_connection.Close();
}
}
My question is: If I call DbContext.something in one of my tests, is it the Dispose method that ensures that this instance of the database is closed when the test ends? So that for the next test when I call DbContext again, its a new instance?
Every unit test should have a new DbContext. You don't want any dependencies between tests. Therefore, calling dispose at the end of a test is correct.
The xUnit documentation describes this. So the class containing your tests could implement IDisposable. By default, xUnit will run every method in your test class in isolation, and will call Dispose, so any object instances are unique per test.
If you want to share object instances, you can use fixtures, but it sounds like you want isolation between your tests, which is there by default.
So if you now directly add test methods to the class in your question, the context should be unique for each test. You should be able to test that by putting breakpoints in your test methods (or Dispose) and then debug the tests, to see what happens.
When I take a look into "SQLite.Net Help the document states:
Dispose - Disposes and finalizes the connection, if applicable.
In other words all SQLiteConnection Members become invalid, all resources are released.
Regards
Martin
Since your test class is used for multiple tests, having a base class for things that should be unique to one test is a bad idea.
You want to control exactly when and how a database is opened and when and how it's removed from memory.
That means your class should not be inherited, but rather used by each single test.
Make your class a normal class that can be instantiated and will provide a DBContext through a method or property. Open and create the database in the constructor, close and remove the database in the dispose method as you already do.
Your test should start with a using block that instantiates this class.
Inside the using block your tests can use the class and the DBContext it provides. the using block will take care of the dispose, no matter how you leave your test (the code might throw an exception after all).
I don't remember how it worked, but I think you can give names to the in-memory databases. It might be a good idea to do so, otherwise you will have to make sure your tests never run in parallel.
I'm a supporter of using Dependency Injection on your application, despite some people consider it add unnecessary complexity to the code.
In the past days I've wondered that, for some scenarios, there may be some waste when using DI.
Let me explain it with code examples:
Using DI
public class Class
{
private Service1 service1;
private Service2 service2;
public MyClass (Service1 service1, Service2 service2)
{
this.service1 = service1;
this.service2 = service2;
}
private int SampleMethod()
{
Console.WriteLine("doing something with service 1");
service1.DoSomething();
return 0;
}
private int SampleMethod2()
{
Console.WriteLine("doing something with service 2");
service2.DoSomethingElse();
return 1;
}
}
What if I rarely call SampleMethod2 and I will be injecting it every single time a Class instance is needed?
Wouldn't that be wasting resources?
I got this question a few days ago and I'm trying to figure out the response. Is it easier not using DI and let every method to create the instance they need when they get used in order to avoid this "waste"?
Is this a justified "waste" thanks to the decoupling that DI provides?
Yes it will be "wasted", but the nature of that waste depends on how its set up:
If Service2 is always created as a new instance; that's fairly expensive
If Service2 is in single instance mode, all its doing is fetching an existing instance (super cheap)
If Class is in single instance mode; its fetching that instance and not injecting anything new
Moreover, this would suggest a violation of SRP. Perhaps Class should be split into two objects, one that depends on Service1 and one that depends on Service 2 (or even both).
Regardless of the above, the "waste" is only important if it actually impacts your application, the benefits of DI vastly outweigh these kinds of problems.
Way 1 new instance
public class LogicPacker : ILogicPacker
{
private IClassDI ClassDI { get; set; }
public LogicPacker (IClassDI ClassDI){
this.ClassDI = ClassDI;
}
private ICommentervice ICommentervice { get; set; }
public ICommentervice Commentervice
{
get { return ICommentervice ?? (ICommentervice = new Commentervice(ClassDI)); }
set { ICommentervice = value; }
}
}
Way 2 AddScoped
public void ConfigureServices(IServiceCollection services)
{
//IClassDI is absolutely add scope not change
services.AddScoped<IClassDI , ClassDI>();
...
services.AddScoped<ICommentservice, Commentservice>();
}
Below this is my service class
public class Commentservice : ICommentservice
{
private IClassDI ClassDI{ get; set; }
public Commentservice(IClassDI ClassDI)
{
this.ClassDI= ClassDI;
}
}
In my code i not sure about performance between use ioc AddScoped or new instance.
Way 1 i think it will be have trouble when i need to inject other to class Commentservice in future it will be make me confuse and annoying.
But Way 1 when i have more class in ILogicPacker i just inject ILogicPacker and need not to inject service anymore to other class is need to use service (if inject to much it will be new instance at constructor to much that i think)
Way 2 is use ioc add that to startup and don't be worry about number of di is need to inject to service.
If have something i think it wrong tell me and comment please.
This isn't really about performance, it's about managing lifetimes and scopes. While instantiating a class incurs some performance hit, it's usually too minuscule to even note, like micro or even nanoseconds. The reason to use DI is to scope dependencies and reuse dependencies.
Consider DbContext, for example. It handles things like change tracking and implements object caches, enabling things like relationship fix-up without having to issue additional queries. However, for those things to function properly, you need to use the same instance everywhere. If you create a new instance every time you use it, then the change tracking can get off, sometimes with disastrous effects, and at the very least, you lose out of all the various performance optimizations it offers. A DI container lets you share dependencies like this without having to think about it.
There's also the issue of handling object disposal, which a lot of people don't think about. If you new up a bunch of stuff in a class, you should also dispose of those things when no longer needed. This is handled via the IDisposable interface, which is deceptively hard to implement correctly. If you fail to dispose of the things you new up, you're essentially leaking memory. Sure, the GC will eventually clean up after you, but relying on the GC is just bad design. A DI container takes the thought out of this as well. It controls the lifetime of the objects it injects, and disposes of them when it truly makes sense to. Your classes are simply injected with the dependencies, so it's no longer the classes' concern as to when or if the resources are disposed. And, of course, reducing concerns is a fundamental paradigm of good design.
I started working recently in a new project where we have thousands of lines of legacy code. We are facing several performance issues. I decided to take a look at the code and saw the following. There's a class:
public class BaseDataAccess
{
private Database dB;
public Database DB
{
get
{
if (dB == null)
{
dB = DatabaseFactory.CreateDatabase();
}
return dB;
}
}
}
And many descendant classes which inherit from the previous base class. Internally, those other classes make use of the DB property, like this:
DataSet ds = DB.ExecuteDataSet(spGetCustomersSortedByAge);
Finally, there's a huge class (5000 lines of code) with tens of methods like the following:
public void ProcessPayments()
{
try
{
List<Employee> employees = new EmployeesDA().SelectAll(null);
foreach (Employee employee in employees)
{
employee.Account = new MovementsDA().SelectAll(employee.Id, DateTime.Now);
...
City city = new CitiesDA().Select(zone.cityId);
...
Management m = new ManagmentDA().Select(city.id);
}
}
catch (Exception ex)
{
...
}
}
Note in the previous method EmployeesDA, MovementsDA, CitiesDA and ManagmentDA all are inheritors of BaseDataAccess and internally use their respective DB properties. Also note they are constantly being instantiated inside foreach loops (many times within 2 levels of nesting).
I think the instantiation itself is suspicious but I'm more concerned about what's going on with the database connections here? Is every DA instantiated opening a new underlying connection? How bad is this code?
As a side note about the solution I was considering in case this code should be fixed: I was considering making every constructor private so the compiler starts complaining about the instantiations and refactor the instantiations with calls to the GetInstance method (singleton pattern) to avoid the recreation of the objects and underlying connections. But, I'm not sure if this could also be dangerous in some way, for example, if the connections may get closed. The current code doesn't have that problem because of the instantiatons happening all the time.
It's a common misconception that object construction is expensive. It's much more expensive than base arithmetic or other machine-level things, but isn't likely the direct source of performance issues.
Using boxed integers for a loop is wasteful for example, but constructing an Employee object in each vs reusing a mutable Employee object isn't going to give meaningful performance advantages.
Many garbage collectors are capable of object memory frame reuse in loops like this. In effect a single object frame is allocated and overwritten on each pass of the loop.
In this specific case there may be a cost if the DA's have significant initialization costs. If that is the case I would refactor the code to create those once outside the loop. I would not use actual static singletons. I would use dependency injection to manage singleton objects if you need it. Static singletons are effectively global variables and are an invitation to stateful coupling and the break down of modularity.
Hi
I am developing a web site
I have a class which is the connection to data base
The class consists a methods that write and read from the data base
Currently, the class is static and also its methods
I call the class from web pages like that:
//mydbClass is the name of the class , not an object
mydbClass.getUserName(userID)
The question is:
Do I need to create a class object, so that each time user asking for a page
a new object is created and it communicates with the data base , like that:
mydbClass mydb = new mydbClass();
mydb.getUserName(userID)
Because if I do not create a new object
So all the users that read or write to the data base
Will use the same static object, then it will be very busy and perhaps it will collapse
I'd love an answer
Thanks
micha
If you want to keep using your class a bit like a static class but with a state , you can implement the singleton pattern
http://en.wikipedia.org/wiki/Singleton_pattern
public class mydbClass{
private static mydbClass _current = new mydbClass();
public static mydbClass Current{
get{
return _current;
}
}
private mydbClass(){}
public User getUserName(userid){
//be sure to create a new connection each times
}
}
The advantage here is that you can simply implement interface in this class, break dependencies and then mock it for testing purpose.
Anyway, you'll always have to create a new connection at each request do not create a static connection object.
You definitely should not use a static class for the connections. If you use a static class then you have to worry about being thread safe because of all the threads using the same class to talk to the database. Just create new database connections each time, and use connection pooling. Connection pooling will make creating new connections each time much faster.
It depends on what you're doing inside the methods.
If, within the method, you open a new connection, use it, and dispose of it, you're fine. No harm, no foul. So long as you're not maintaining state, you're good to go.
On the other hand, if you're maintaining state, you've got problems, as thread-safety enters the picture. In that case, you're much better off just creating a class that's designed to be instantiated.
I would advice static class, if you see small number of concurrent users querying the Static class.A static class can easily handle sufficient requests serially (say a 20 + in a second).
The database routine is more likely bottleneck, depending on the query.
Take care of thread safety**