user137348
user137348

Reputation: 10332

Class design question (Disposable and singleton behavior)

The Repository class has singleton behavior and the _db implements the disposable pattern. As excepted the _db object gets disposed after the first call and because of the singleton behavior any other call of _db will crash.

 [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
 public class Repository : IRepository
 {
    private readonly DataBase _db;

    public Repository(DataBase db)
    {
        _db = db;
    }

    public int GetCount()
    {
        using(_db)
        {
            return _db.Menus.Count();
        }
    }

    public Item GetItem(int id)
    {
        using(_db)
        {
            return _db.Menus.FirstOrDefault(x=>x.Id == id);
        }
    } 

  }

My question is, is there any way to design this class to work properly without removing the singleton behavior? The Repositoryclass will be serving big amount of requests.

Upvotes: 0

Views: 721

Answers (2)

Steven
Steven

Reputation: 172865

When you supply a DataBase instance to the Repository, this means creation and disposal is not in the scope of the Repository class. Therefore, Repository should not dispose that instance. You should remove the using statements, and you'll be fine. Write the Repository as follows:

public class Repository : IRepository
{
    private readonly DataBase _db;

    public Repository(DataBase db)
    {
        _db = db;
    }

    public int GetCount()
    {
        return _db.Menus.Count();
    }

    public Item GetItem(int id)
    {
        return _db.Menus.FirstOrDefault(x=>x.Id == id);
    } 
}

Upvotes: 2

Ray
Ray

Reputation: 21905

When you do this:

using(_db)

you are guaranteeing that Dispose() will be called on your object.

I would suggest changing this to use a static class with a private static member for _db.

public static class Repository {
  private static DataBase _db; 

  // static constructor
  static Repository () {
    _db = new Database();
  }

  public static int GetCount() {
    return _db.Menus.Count();
  }
  public Item GetItem(int id) {
    return _db.Menus.FirstOrDefault(x=>x.Id == id);
  }
}

Upvotes: 2

Related Questions