0

I am coding a MVC 5 internet application, and am having some trouble with initializing a Lazy object.

Here is my code:

public Lazy<IGenericRepository<Account>> accounts;
public IGenericRepository<Account> accountsNotLazy;

I am wanting to initialize these two variables in the constructor call to the class.

Here is the constructor code;

public GenericMultipleRepository(DbContext dbContext)
{
    this.dbContext = dbContext;
    accounts = new Lazy<GenericRepository<Account>>(dbContext);
    accountsNotLazy = new GenericRepository<Account>(dbContext);
}

Can I please have some help with this code?

Thanks in advance.

EDIT

I am wanting the exact same initialization as the accountsNotLazy variable, but using Lazy loading. The accountsNotLazy variable is initializing correctly, how come the accounts is not? The only difference is the Lazy keyword.

These are the errors:

The best overloaded method match for 'System.Lazy>.Lazy(System.Func>)' has some invalid arguments

As well as:

cannot convert from 'System.Data.Entity.DbContext' to 'System.Func>'

Here is the GenericRepository class:

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    protected DbSet<TEntity> DbSet;

    private readonly DbContext _dbContext;

    public GenericRepository(DbContext dbContext)
    {
        _dbContext = dbContext;
        DbSet = _dbContext.Set<TEntity>();
    }

    public GenericRepository()
    {
    }

    public IQueryable<TEntity> GetAll()
    {
        return DbSet;
    }

    public async Task<TEntity> GetByIdAsync(int id)
    {
        return await DbSet.FindAsync(id);
    }

    public IQueryable<TEntity> SearchFor(Expression<Func<TEntity, bool>> predicate)
    {
        return DbSet.Where(predicate);
    }

    public async Task EditAsync(TEntity entity)
    {
        _dbContext.Entry(entity).State = EntityState.Modified;
        await _dbContext.SaveChangesAsync();
    }

    public async Task InsertAsync(TEntity entity)
    {

        DbSet.Add(entity);
        await _dbContext.SaveChangesAsync();
    }

    public async Task DeleteAsync(TEntity entity)
    {
        DbSet.Remove(entity);
        await _dbContext.SaveChangesAsync();
    }
}
Simon
  • 7,991
  • 21
  • 83
  • 163
  • 2
    Pretty sure you can't pass a `dbContext` into the constructor like that. It requires a `Func` – DavidG Dec 28 '14 at 04:35
  • The code can't compile as shown - so there is no way this code has runtime "argument out of range" exception. Please check if code in the post is actually one you have problem with. – Alexei Levenkov Dec 28 '14 at 04:44

3 Answers3

1

As many have mentioned that you need to pass a Func<T>, but the expression suggested as the answer is incorrect.

Initialize your accounts variable as follows -

accounts = new Lazy<IGenericRepository<Account>>(() => new GenericRepository<Account>(dbContext));

Do note that when you want to access your instance of GenericRepository lazily, you would need to access Value property of Lazy class.. like so - accounts.Value, which will be of type GenericRepository<Account>

Vikas Gupta
  • 4,455
  • 1
  • 20
  • 40
  • I am getting the following error: Cannot implicitly convert type 'System.Lazy>' to 'System.Lazy>' – Simon Dec 28 '14 at 06:41
  • Ok.. you have a difference in your declaration of the variable.. vs the instance of `Lazy` you were creating.. I initially went by the latter, and only corrected the `Func`.. Now I have updated the generic type parameter being passed as well.. i.e. from `GenericRepository` to `IGenericRepository` – Vikas Gupta Dec 28 '14 at 06:45
0

The constructor for Lazy<T> requires a parameter of type Func<T>. You may want to try this instead:

accounts = new Lazy<GenericRepository<Account>>(() => { return dbContext; });
DavidG
  • 113,891
  • 12
  • 217
  • 223
  • "argument out of range exception" - is runtime exception, which simply means code in the post does not show problem OP has... – Alexei Levenkov Dec 28 '14 at 04:42
  • @AlexeiLevenkov I agree, but I can see no way that the code posted will compile given any of the constructors available. – DavidG Dec 28 '14 at 04:44
  • I am getting this error with your code: Cannot convert lambda expression to type 'bool' because it is not a delegate type. As well as: Cannot convert lambda expression to delegate type 'System.Func>' because some of the return types in the block are not implicitly convertible to the delegate return type. – Simon Dec 28 '14 at 05:10
0

The constructor of the Lazy<T> class is

Lazy<T>(Func<T>)

You can change your GenericMultipleRepository constructor to as follow:

public GenericMultipleRepository(DbContext dbContext)
{
    this.dbContext = dbContext;
    accounts = new Lazy<GenericRepository<Account>>(() => { return dbContext; });
    accountsNotLazy = new GenericRepository<Account>(dbContext);
}
Dan
  • 971
  • 1
  • 8
  • 22
  • I am getting this error with your code: Cannot convert lambda expression to type 'bool' because it is not a delegate type. – Simon Dec 28 '14 at 04:52