0

I currently have 4 static classes to access the data layer : one for each type of operations (select, insert, update, delete).

public static class DataAccess_SELECT
{
    private static MyDBContext db = new MyDBContext();

    public static List<T_News> GetAllNews()
    {
        return db.T_News.AsNoTracking().ToList();
    }

    public static List<T_News> GetAllNewsActif()
    {
        return db.T_News.AsNoTracking().Where(x => !x.DateDesactivation.HasValue || (DateTime.Now > x.DateActivation && DateTime.Now < x.DateDesactivation)).ToList();
    }

    public static List<T_Sondage> GetAllSondages()
    {
        return db.T_Sondage.AsNoTracking().ToList();
    }

    // (...)
}

I've read that it should be avoided to use static classes in that situation, how should I organize this otherwise ?

Thanks for your advice.

1 Answer 1

1

First, instances of your database context shouldn't be defined as static, so you'll need to take care of that as well.

As to your main question about how to handle dependencies without making everything static:

You define a new property that stores an instance of a class that your current class needs (the dependency), this instance is then initialized either via an Inversion of Control container (IoC container), or directly in the constructor.

Whether to initialize the instances in the in constructor or let the IoC container handle everything is another matter, but you'll need to pay attention to the lifetime of the created objects, which ones should be short-lived, and which ones can be reused.

//pattern #1
public class DataAccess {
    private readonly DatabaseContext _databaseContext;
    public DataAccess() {
        //initialized in the constructor
        _databaseContext = new DatabaseContext();
    }
}

//pattern #2
public class DataAccess {
    private readonly DatabaseContext _databaseContext;
    public DataAccess(DatabaseContext databaseContext) {
        //The IoC container supplies the instace
        _databaseContext = databaseContext;
    }
}

And the class that uses the DataAccess class will also utilize the same pattern, all the way up in your call chain.

You can read about dependency injection, and in the mean time use pattern #1, and again pay attention to object lifetimes.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your detailed answer @rhytonix, it helps a lot. Could you tell me a bit more about object lifetimes ? Do you have an example of how you would manage that ?
Another question, if I'm going to use the DataAccess in some of the views, is there something specific I should do or can I just create an instance of DataAccess and use it ? Thanks again.
There are three main object lifetimes (since the dependency is injected, the injector should determine the lifetime of the injected objects): 1. Transient, each time a container is asked for an instance of an object, it returns a new instance. 2. Singleton, the container returns the same instance for all requests of the object -the same instance is reused all the time-. 3. per request: the same instance is returned within the same web request, new web requests receive new instances. The naming of the lifetimes might differ from one IoC to another, but they share the same basic idea.
e.g. DbContext isn't thread-safe, so it shouldn't be defined as static (nor singleton), instead it gets defined as a per-request dependency. You can look into using an IoC container to handle the dependencies for you. Containers have a simple format of registering dependencies, their expected lifetimes, and then they magically resolve all the constructor dependencies for you at runtime. The format looks something like: Register<Type>.WithLifeTime(lifeTime). One good IoC with decent documentation is Autofac. You might want to build a small application first before refactoring your current one.
You can get an instance of DataAccess from the view but this isn't the recommended approach of using the IoC container (this is known as service locator anti-pattern), instead you should rely on the IoC to resolve the dependencies in the constructors of your classes. Also, the view should receive the prebuilt model from the controller, not make database requests itself.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.