Microsoft.AspNetCore.All : v2.0.3 | Zarif : v1.50.2
En iyi uygulamaları doğru kullanıp kullanmadığımdan emin değilim, ancak birden çok bağlantı dizesini işlemek için bunu bu şekilde yapıyorum .
Yalnızca 1 bağlantı dizeniz varsa kolaydır
Startup.cs
using System.Data;
using System.Data.SqlClient;
namespace DL.SO.Project.Web.UI
{
public class Startup
{
public IConfiguration Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
string dbConnectionString = this.Configuration.GetConnectionString("dbConnection1");
services.AddTransient<IDbConnection>((sp) => new SqlConnection(dbConnectionString));
services.AddScoped<IDiameterRepository, DiameterRepository>();
}
}
}
DiameterRepository.cs
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class DiameterRepository : IDiameterRepository
{
private readonly IDbConnection _dbConnection;
public DiameterRepository(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public IEnumerable<Diameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return _dbConnection.Query<Diameter>(sql);
}
}
}
1'den fazla bağlantı dizeniz varsa sorunlar
Kullanıldığı Dapper
için IDbConnection
, farklı veritabanı bağlantılarını ayırt etmenin bir yolunu düşünmeniz gerekir.
IDbConnection
Farklı veritabanı bağlantılarına karşılık gelen , 'miras alınan' birden çok arabirim oluşturmaya ve SqlConnection
farklı veritabanı bağlantı dizeleriyle enjekte etmeye çalıştım Startup
.
Bu başarısız oldu çünkü sadece sınıftan değil , aynı zamanda sınıftan SqlConnection
miras alır DbConnection
ve DbConnection
onu ekler . Böylece, özel arayüzleriniz sadece uygulamayı kullanamayacak.IDbConnection
Component
SqlConnection
Ayrıca DbConnection
farklı bağlantı dizesi alan kendi sınıfımı oluşturmaya çalıştım . Bu çok karmaşık çünkü tüm yöntemleri DbConnection
sınıftan uygulamanız gerekiyor. Yardımını kaybettin SqlConnection
.
Ne yapıyorum
- Bu sırada
Startup
tüm bağlantı dizesi değerlerini bir sözlüğe yükledim. Ayrıca enum
sihirli dizelerden kaçınmak için tüm veritabanı bağlantı adları için bir de oluşturdum .
- Sözlüğü Singleton olarak enjekte ettim.
- Enjekte etmek yerine
IDbConnection
, bunu IDbConnectionFactory
tüm depolar için Geçici olarak yarattım ve enjekte ettim. Artık tüm depolar IDbConnectionFactory
yerine alıyor IDbConnection
.
- Doğru bağlantıyı ne zaman seçmelisiniz? Tüm depoların kurucusunda! İşleri temizlemek için, depo temel sınıfları oluşturdum ve depoların temel sınıflardan miras almasını sağladım. Doğru bağlantı dizesi seçimi temel sınıflarda gerçekleşebilir.
DatabaseConnectionName.cs
namespace DL.SO.Project.Domain.Repositories
{
public enum DatabaseConnectionName
{
Connection1,
Connection2
}
}
IDbConnectionFactory.cs
using System.Data;
namespace DL.SO.Project.Domain.Repositories
{
public interface IDbConnectionFactory
{
IDbConnection CreateDbConnection(DatabaseConnectionName connectionName);
}
}
DapperDbConenctionFactory - kendi fabrika uygulamam
namespace DL.SO.Project.Persistence.Dapper
{
public class DapperDbConnectionFactory : IDbConnectionFactory
{
private readonly IDictionary<DatabaseConnectionName, string> _connectionDict;
public DapperDbConnectionFactory(IDictionary<DatabaseConnectionName, string> connectionDict)
{
_connectionDict = connectionDict;
}
public IDbConnection CreateDbConnection(DatabaseConnectionName connectionName)
{
string connectionString = null;
if (_connectDict.TryGetValue(connectionName, out connectionString))
{
return new SqlConnection(connectionString);
}
throw new ArgumentNullException();
}
}
}
Startup.cs
namespace DL.SO.Project.Web.UI
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
var connectionDict = new Dictionary<DatabaseConnectionName, string>
{
{ DatabaseConnectionName.Connection1, this.Configuration.GetConnectionString("dbConnection1") },
{ DatabaseConnectionName.Connection2, this.Configuration.GetConnectionString("dbConnection2") }
};
services.AddSingleton<IDictionary<DatabaseConnectionName, string>>(connectionDict);
services.AddTransient<IDbConnectionFactory, DapperDbConnectionFactory>();
services.AddScoped<IDiameterRepository, DiameterRepository>();
}
}
}
DiameterRepository.cs
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class DiameterRepository : DbConnection1RepositoryBase, IDiameterRepository
{
public DiameterRepository(IDbConnectionFactory dbConnectionFactory)
: base(dbConnectionFactory) { }
public IEnumerable<Diameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return base.DbConnection.Query<Diameter>(sql);
}
}
}
DbConnection1RepositoryBase.cs
using System.Data;
using DL.SO.Project.Domain.Repositories;
namespace DL.SO.Project.Persistence.Dapper
{
public abstract class DbConnection1RepositoryBase
{
public IDbConnection DbConnection { get; private set; }
public DbConnection1RepositoryBase(IDbConnectionFactory dbConnectionFactory)
{
this.DbConnection = dbConnectionFactory.CreateDbConnection(DatabaseConnectionName.Connection1);
}
}
}
Daha sonra, diğer bağlantılarla konuşması gereken diğer havuzlar için, onlar için farklı bir depo temel sınıfı oluşturabilirsiniz.
using System.Data;
using DL.SO.Project.Domain.Repositories;
namespace DL.SO.Project.Persistence.Dapper
{
public abstract class DbConnection2RepositoryBase
{
public IDbConnection DbConnection { get; private set; }
public DbConnection2RepositoryBase(IDbConnectionFactory dbConnectionFactory)
{
this.DbConnection = dbConnectionFactory.CreateDbConnection(DatabaseConnectionName.Connection2);
}
}
}
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class ParameterRepository : DbConnection2RepositoryBase, IParameterRepository
{
public ParameterRepository (IDbConnectionFactory dbConnectionFactory)
: base(dbConnectionFactory) { }
public IEnumerable<Parameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return base.DbConnection.Query<Parameter>(sql);
}
}
}
Umarım tüm bunlar yardımcı olur.