我正忙于在C#中开发一个类库项目,以便将来重用并附加到不同的项目中。它主要用于表值参数。我的问题是,如何将SQL连接传递给它?连接将在.dll附加到的另一个(主项目)中实例化。
我目前有一个类库项目,并且在相同的解决方案中创建了一个控制台应用程序项目,用于测试目的。
最后一个要求是我不想使用ConfigurationManager,因为连接字符串不会存储在app.config或web.config中,默认情况下必须将查询传递回调用应用程序。
我来自下面的几个链接,但我真的无法使用:
请原谅noobness,我是7周的专业编程。
答案 0 :(得分:3)
在您的dll中,只需要IDbConnection
或IDbCommand
。然后,所有方法都针对数据访问接口进行了适当的抽象。
例如:
在您的共享dll中
public static int LookUpIntForSomething(IDbConnection connection)
{
using (var command = connection.CreateCommand())
{
// use command.
}
}
在您的通话应用中
using (var connection = new SqlConnection("ConnectionString"))
{
var int = DbQueries.LookupIntForSomething(connection);
}
答案 1 :(得分:0)
这是依赖注入的绝佳示例。我建议使用企业库统一这类东西。在您的数据访问层库中,我将定义interface:
public interface IConnectionProvider {
string ConnectionString { get; }
}
public interface IAccountProvider {
Account GetAccountById(int accountID);
}
internal class AccountProvider : IAccountProvider {
private IConnectionProvider _connectionProvider;
public AccountProvider(IConnectionProvider connectionProvider) {
if (connectionProvider == null) {
throw new ArgumentNullException("connectionProvider");
}
_connectionProvider = connectionProvider;
}
public Account GetAccountById(int accountID) {
Account result;
using(var conn = new SqlConnection(connectionProvider)) {
// retrieve result here
}
return result;
}
}
public static class Bootstrapper {
public static void Init() {
ServiceLocator.AddSingleton<IAccountProvider, AccountProvider>();
}
}
然后在使用您的数据访问库的任何程序集中,您可以定义IConnectionProvider的实现,如下所示:
internal class WebConnectionProvider : IConnectionProvider {
public string ConnectionString { get { return "Server=..."; } }
}
internal static class WebBootstrapper {
public static void Init() {
Bootstrapper.Init();
ServiceLocator.AddSingleton<IConnectionProvider, WebConnectionProvider>();
}
}
在程序集中调用WebBootstrapper.Init()之后的任何地方都可以使用:
var accountProvider = ServiceLocator.Resolve<IAccountProvider>();
accountProvider.GetAccountById(1);
服务定位器:
using System;
using Microsoft.Practices.Unity;
public class ServiceLocator {
private IUnityContainer m_Container = new UnityContainer();
public void Add<TFrom, TTo>() where TTo : TFrom {
m_Container.RegisterType<TFrom, TTo>();
}
public void BuildUp<T>(T instance) {
m_Container.BuildUp<T>(instance);
}
public void BuildUp(Type type, object instance) {
m_Container.BuildUp(type, instance);
}
public void AddSingleton<TFrom, TTo>() where TTo : TFrom {
m_Container.RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager());
}
public void AddInstance<T>(T instance) {
m_Container.RegisterInstance<T>(instance);
}
public T Resolve<T>() {
return m_Container.Resolve<T>();
}
private static ServiceLocator m_Instance;
public static ServiceLocator Instance {
get { return m_Instance; }
}
static ServiceLocator() {
m_Instance = new ServiceLocator();
}
}
答案 2 :(得分:-1)
如果我理解你的要求,我不确定,我会设置一个静态结构
public static struct ConnectionString
{
public int ID;
public string Connection;
public override string ToString()
{
return Connection;
}
public static ConnectionString DataBase1 = new ConnectionString{ ID = 1 , Connection = "YourConnectionStringhere"};
public static ConnectionString DataBase2 = new ConnectionString{ ID = 2 , Connection = "YourConnectionString2here"};
}
然后将其用作
public void SomeMethod()
{
var I = ReferencedDll.DoSomething(ConnectionString.DataBase1.ToString());
}
或
public void SomeMethod()
{
var ClassFromDll = new ReferencedDll.SomeClass(ConnectionString.DataBase1.ToString());
ClassFromDll.DoSomething();
}
当然这会使你的连接字符串硬编码,这是不理想的