3
Good morning friends. I hit a rough patch and I’m not getting past it.
I have 2 projects, a webapi and a standard class, both in dot net core.
In my standard design, I am working with Repository to abstract CRUD in mongoDB.
Follows the classes of the Repository:
INTERFACE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace Model.Repository
{
public interface IRepositoryMongo<TEntity> where TEntity : Mongo.MongoID
{
void Add(string identificador, TEntity entity);
void AddAll(string identificador, List<TEntity> entity);
void Edit(string identificador, TEntity entity);
void Delete(string identificador, TEntity entity);
List<TEntity> Get(string identificador, Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null);
}
}
Implementation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using MongoDB.Bson;
using MongoDB.Driver;
using Microsoft.Extensions.Configuration;
namespace Model.Repository
{
public class RepositoryMongo<TEntity> : IRepositoryMongo<TEntity> where TEntity : Mongo.MongoID
{
private MongoDB.Driver.IMongoDatabase dataBase;
public RepositoryMongo(IConfiguration configuration)
{
var client = new MongoDB.Driver.MongoClient(configuration.GetConnectionString("defaultConnection"));
this.dataBase = client.GetDatabase(configuration.GetConnectionString("dataBaseName"));
}
public void Add(string identificador, TEntity entity)
{
var dados = this.dataBase.GetCollection<TEntity>(typeof(TEntity).Name + "_" + identificador);
dados.InsertOne(entity);
}
public void AddAll(string identificador, List<TEntity> entity)
{
var dados = this.dataBase.GetCollection<TEntity>(typeof(TEntity).Name + "_" + identificador);
dados.InsertMany(entity);
}
public void Edit(string identificador, TEntity entity)
{
var dados = this.dataBase.GetCollection<TEntity>(typeof(TEntity).Name + "_" + identificador);
var filtro = Builders<TEntity>.Filter.Eq("_id", entity.Id);
dados.ReplaceOne(filtro, entity);
}
public void Delete(string identificador, TEntity entity)
{
var dados = this.dataBase.GetCollection<TEntity>(typeof(TEntity).Name + "_" + identificador);
var filtro = Builders<TEntity>.Filter.Eq("_id", entity.Id);
dados.DeleteOne(filtro);
}
public virtual List<TEntity> Get(string identificador, Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
{
var dados = this.dataBase.GetCollection<TEntity>(typeof(TEntity).Name + "_" + identificador);
return dados.Find<TEntity>(new BsonDocument()).ToList();
}
}
}
Class of Mongo to force ID use on everything
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json;
namespace Model.Mongo
{
public class MongoID
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
}
}
So in the startup.Cs of my webAPI, I do the following::
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.IO;
namespace loginAPI
{
public class Startup
{
public IConfiguration Configuration { get; set; }
public IConfiguration minhaConfiguracao {get;set;}
public Startup(IConfiguration configuration)
{
Configuration = configuration;
// evitar possiveis conflitos da configuração default
this.minhaConfiguracao = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// aqui está funcionando perfeitamente
services.AddSingleton<IConfiguration>(this.minhaConfiguracao);
// aqui se eu não instanciar o tipo, ele da erro
services.AddScoped<Model.Repository.IRepositoryMongo<Model.Login.Login>, Model.Repository.RepositoryMongo<Model.Login.Login>>();
// tentei fazer isso aqui e nao deu certo:
//services.AddScoped<Model.Repository.IRepositoryMongo<Model.Mongo.MongoID>, Model.Repository.RepositoryMongo<Model.Mongo.MongoID>>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
}
And finally, my controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
namespace loginAPI.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller
{
Model.Repository.IRepositoryMongo<Model.Login.Login> repository;
public ValuesController(Model.Repository.IRepositoryMongo<Model.Login.Login> repository)
{
this.repository = repository;
}
// GET api/values
[HttpGet]
public IActionResult Get()
{
return Ok(this.repository.Get(""));
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public IActionResult Post([FromBody]Model.Login.Login value)
{
this.repository.Add("",value);
return Ok (value);
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]Model.Login.Login value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
I want to know if there is any way to do the injection in a generic way, because all the types that I will use will necessarily inherit from Mongoid
So I don’t want to keep doing
services.AddScoped<Model.Repository.IRepositoryMongo<Model.x>, Model.Repository.RepositoryMongo<Model.x>>();
For every model I use in my controller/service