I am new to .NET core and designing Asp.net core application layered architecture. We are using generic Repository with Unit of Work repository pattern. Completed the generic repository method, need to have some idea for Unit Of Work with collection.
Generic Repository
public interface IMongoRepository<TDocument> where TDocument : IAudiableEntity
{
void InsertOne(TDocument document);
Task<TDocument> InsertOneAsync(TDocument document);
void InsertMany(ICollection<TDocument> documents);
Task InsertManyAsync(ICollection<TDocument> documents);
void ReplaceOne(TDocument document);
Task ReplaceOneAsync(TDocument document);
void DeleteOne(Expression<Func<TDocument, bool>> filterExpression);
Task DeleteOneAsync(Expression<Func<TDocument, bool>> filterExpression);
void DeleteById(string id);
Task DeleteByIdAsync(string id);
void DeleteMany(Expression<Func<TDocument, bool>> filterExpression);
Task DeleteManyAsync(Expression<Func<TDocument, bool>> filterExpression);
}
public class MongoRepository<TDocument> : IMongoRepository<TDocument>
where TDocument : IAudiableEntity
{
private readonly IMongoCollection<TDocument> _collection;
public MongoRepository(IMongoDbSettings settings)
{
var database = new MongoClient(settings.ConnectionString).GetDatabase(settings.DatabaseName);
_collection = database.GetCollection<TDocument>(GetCollectionName(typeof(TDocument)));
}
private protected string GetCollectionName(Type documentType)
{
return ((BsonCollectionAttribute)documentType.GetCustomAttributes(
typeof(BsonCollectionAttribute),
true)
.FirstOrDefault())?.CollectionName;
}
public virtual void InsertOne(TDocument document)
{
_collection.InsertOne(document);
}
public virtual async Task<TDocument> InsertOneAsync(TDocument document)
{
await _collection.InsertOneAsync(document);
return document;
}
public void InsertMany(ICollection<TDocument> documents)
{
_collection.InsertMany(documents);
}
public virtual async Task InsertManyAsync(ICollection<TDocument> documents)
{
await _collection.InsertManyAsync(documents);
}
public void ReplaceOne(TDocument document)
{
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, document.Id);
if (document is Slides slide)
{
slide.IsDirty = true;
}
_collection.FindOneAndReplace(filter, document);
}
public void ReplaceWODirtyOne(TDocument document)
{
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, document.Id);
_collection.FindOneAndReplace(filter, document);
}
public virtual async Task ReplaceOneAsync(TDocument document)
{
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, document.Id);
if (document is Slides slide)
{
slide.IsDirty = true;
}
await _collection.FindOneAndReplaceAsync(filter, document);
}
public virtual async Task ReplaceWODirtyOneAsync(TDocument document)
{
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, document.Id);
await _collection.FindOneAndReplaceAsync(filter, document);
}
public void DeleteOne(Expression<Func<TDocument, bool>> filterExpression)
{
_collection.FindOneAndDelete(filterExpression);
}
public Task DeleteOneAsync(Expression<Func<TDocument, bool>> filterExpression)
{
return Task.Run(() => _collection.FindOneAndDeleteAsync(filterExpression));
}
public void DeleteById(string id)
{
var objectId = new ObjectId(id);
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, objectId);
_collection.FindOneAndDelete(filter);
}
public Task DeleteByIdAsync(string id)
{
return Task.Run(() =>
{
var objectId = new ObjectId(id);
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, objectId);
_collection.FindOneAndDeleteAsync(filter);
});
}
public void DeleteMany(Expression<Func<TDocument, bool>> filterExpression)
{
_collection.DeleteMany(filterExpression);
}
public Task DeleteManyAsync(Expression<Func<TDocument, bool>> filterExpression)
{
return Task.Run(() => _collection.DeleteManyAsync(filterExpression));
}
}
How can do the Unit of work here, let me know the possibilities.
It will be better for you to understand if I answer your question by giving an example.
Let's assume you have a repository named 'ApplicationUser'
Your interface will look like this
And Your Repository is here;
İf you want to use UnitOfWork pattern, you should add your interface inside to IUnitOfWork class
The example may not suit your structure, but the structure you need to create will look like this. Also, it doesn't matter which database you use for EF.