1

我正忙着用 C# 开发一个类库项目,以便将来重用并附加到不同的项目中。它将主要用于表值参数。我的问题是,如何将 SQL 连接传递给它?该连接将在 .dll 附加到的另一个(主项目)中实例化。

我目前有一个类库项目,并在同一解决方案中创建了一个控制台应用程序项目,用于测试目的。

最后一个要求是我不想使用 ConfigurationManager,因为连接字符串不会存储在 app.config 或 web.config 中,并且默认情况下必须将查询传递回调用应用程序。

我遇到了几个类似下面的链接,但没有什么我可以真正使用的:

共享连接字符串

请原谅菜鸟,我已经进入专业编程 7 周了。

4

3 回答 3

3

在您的 dll 中,只需要一个IDbConnectionor 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);
}
于 2013-08-06T12:57:11.890 回答
0

这是依赖注入的绝佳示例。我建议对这类东西使用企业库统一。在您的数据访问层库中,我将定义接口:

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();
  }
}
于 2013-08-06T13:14:28.430 回答
-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();
 }

当然,这会使您的连接字符串硬编码,这并不理想

于 2013-08-06T12:46:59.503 回答