2011-04-10 5 views
9

Empecé a jugar con MongoDB (C#) y traté de transferir un repositorio desde el marco de la entidad. Estoy usando el controlador oficial C# 1.0. Ahora he hecho algo como esto:Patrón de repositorio con MongoDB: dónde inicializar la base de datos

internal class MongoContext 
{ 
    public MongoContext(string constring) 
    { 
     MongoServer server = MongoServer.Create(constring); 
     this.myDB = server.GetDatabase("MyDB"); 

     BsonClassMap.RegisterClassMap<VoyageNumber>(cm => 
      { cm.MapField<string>(p => p.Id); }); 
     BsonClassMap.RegisterClassMap<Schedule>(cm => 
     { cm.MapField<DateTime>(p => p.EndDate); cm.MapField<DateTime>(p => p.StartDate); }); 
     BsonClassMap.RegisterClassMap<Voyage>(cm => 
      { cm.MapIdField<VoyageNumber>(p => p.VoyageNumber); cm.MapField<Schedule>(p => p.Schedule); }); 

    } 

    private MongoDatabase myDB; 
    public MongoDatabase MyDB 
    { get { return this.myDB; } } 
} 

Me continuación, seguir y poner en práctica el Repositorio de la siguiente manera:

public class MongoVoyageRepository : IVoyageRepository 
{ 
    private readonly MongoContext context; 

    public MongoVoyageRepository(string constring) 
    { 
     this.context = new MongoContext(constring); 
    } 

    public void Store(Domain.Model.Voyages.Voyage voyage) 
    { 

     MongoCollection<Voyage> mongoVoyages = context.MyDB.GetCollection<Voyage>("Voyages"); 

     //store logic... 

    } 

} 

Ahora me gustaría saber si es una buena decisión para crear instancias de una "contexto" como este en términos de rendimiento. ¿Tiene sentido poner los mapas BsonClass allí? Gracias por su aporte.

Respuesta

2

Supongo que no tiene sentido registrar mapeo de clases cada vez que crea su clase de repositorio. Como el controlador MongoDB C# gestiona las conexiones a MongoDB internamente, me parece que es mejor crear MongoServer y registrar el mapeo de clases solo una vez, durante el inicio de la aplicación y luego usarlo.

estoy usando Singleton con el fin de crear MongoServer sola vez

public class MongoRead : MongoBase 
{ 
    public MongoRead(MongoServer server) 
      : base(server) 
    { 

    } 


    public override MongoDatabase Database 
    { 
    get { return Server.GetDatabase("myDb"); } 
    } 

    public MongoCollection Logs 
    { 
    get { return Database.GetCollection("logs"); } 
    } 

    private static MongoRead _instance = null; 

    public static MongoRead Instance 
    { 
    get 
     { 
     if (_instance == null) 
     { 
      _instance = RegisterMongoDb(); 

     } 

     return _instance; 
     } 

    } 

    private static MongoRead RegisterMongoDb() 
    { 
     var readServer = MongoServer.Create(connectionString); 
     var read = new MongoRead(readServer); 

     var myConventions = new ConventionProfile(); 
     myConventions.SetIdMemberConvention(new NoDefaultPropertyIdConvention()); 
     BsonClassMap.RegisterConventions(myConventions, t => true); 

     return read; 
    } 

} 

lo que también puede utilizar por encima de la clase en su repositorio:

public class MongoVoyageRepository : IVoyageRepository 
{ 
    private readonly MongoRead context 
    { 
     get { return MongoRead.Instance; } 
    }; 

    public MongoVoyageRepository() 
    { 
    } 

    public void Store(Domain.Model.Voyages.Voyage voyage) 
    { 
      MongoCollection<Voyage> mongoVoyages = 
        context.Database.GetCollection<Voyage>("Voyages"); 
      //store logic... 
    } 

} 
+0

Eso funciona, pero he transformado la propiedad Instancia en un método que acepta una cadena de conexión ya que quiero inyectar la cadena de conexión en el repositorio (IoC). – hoetz

+0

@Malkier: También estoy usando IoC y DI, acabo de hacer 'Instance' ya que muchos desarrolladores no saben sobre IoC, DI o parece difícil de entender;) –

+0

@AndrewOrsich ¿cuál es la clase' NoDefaultPropertyIdConvention'? –

11
// entity base 
public class MongoEntity { 
    public ObjectId _id { get; set; } 
} 

//user entity 
public class Users : MongoEntity { 
    public string UserName { get; set; } 
    public string Password { get; set; } 
} 


// simple repository 
public class Repository { 

    private MongoDatabase _db; 
    public MongoDatabase Database { get; private set; } 
    public Repository(string constr, string dbname) { 
     var server = MongoServer.Create(constr); 
     _db = server.GetDatabase(dbname); 
     Database = _db; 
    } 

    private MongoCollection<T> GetCollection<T>() where T : MongoEntity { 
     return _db.GetCollection<T>(typeof(T).Name); 
    } 

    public IEnumerable<T> List<T>() where T : MongoEntity { 
     return GetCollection<T>().FindAll(); 
    } 

    public IEnumerable<T> List<T>(Expression<Func<T, bool>> exp) where T : MongoEntity { 
     return GetCollection<T>().AsQueryable<T>().Where(exp); 
    } 

    public T Single<T>(Expression<Func<T, bool>> exp) where T : MongoEntity { 
     return List<T>(exp).SingleOrDefault(); 
    } 

    public void Insert<T>(T entity) where T : MongoEntity { 
     GetCollection<T>().Insert<T>(entity); 
    } 

    public void Insert<T>(ICollection<T> entities) where T : MongoEntity { 
     GetCollection<T>().InsertBatch(entities); 
    } 

    // Update, Delete method etc ... 



} 



// example 
var repository = new Repository("mongodb://localhost", "test"); 
repository.Single<Users>(u => u.UserName == "myUserName"); 
0

this también es interesante si quieres para usar el patrón de repositorio.

Cuestiones relacionadas