首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于多环境的C#类库的配置

用于多环境的C#类库的配置
EN

Stack Overflow用户
提问于 2016-03-05 23:12:10
回答 2查看 1K关注 0票数 0

我正在C# .NET Framework4.6中构建一个类库,它整合和简化了对各种后端数据源的数据访问。这些数据源是Azure表、Azure Blobs、Redis、DocumentDB数据和外部REST。所有这些数据都被多个系统在不同的平台上使用。在这一点上,我们有一个巨大的混乱的不同的系统,所有需要单独维护,每次一个后端数据源的变化,甚至轻微。更改表意味着我们需要在5-7码基之间更新代码。

问题是这个类库将从ASP.NET 2& 4、ASP.NET Core1.0和Windows应用程序中使用。它也有可能在其他环境中使用。

挑战在于,每个位置都需要一种方法来设置它们自己的配置字符串和访问键。我希望这只是配置文件的一部分,您可以添加您的信息。库将读取密钥并准备就绪,就像许多库所做的那样。

我的问题是,似乎没有通用的方式访问这些平台上的设置。我不希望为每个可以使用的平台创建一个自定义设置访问器。

有人能给我一个简单易用的解决方案吗?理想情况下,它不需要太多的外部依赖。

作为一个附带的问题,对于这些不同的系统,我预期还有什么其他的问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-06 02:48:52

如果它只是一个需要连接字符串的类,那么将连接字符串放在类的构造函数中。该类不应该直接从web.config或其他任何地方获取字符串。

如下所示:

代码语言:javascript
运行
复制
public class ReadsSomethingFromSql
{
    private readonly string _connectionString;

    public ReadsSomethingFromSql(string connectionString)
    {
        _connectionString = connectionString;
    }

    public void InsertSomethingIntoSql()
    {
        using (var connection = new SqlConnection(_connectionString))
        {
            //Do something with connection string
        }
    }
}

这样,这个类就不负责阅读web.config的内容了。这可能会让人感到困惑,因为使用该类的人现在可能知道类期望连接字符串在web.config中。通过将其放入构造函数中,类显然需要一个连接字符串。

如果不使用依赖项注入,则调用方法可以这样做:

代码语言:javascript
运行
复制
var reader = new ReadsSomethingFromSql(
    ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString);

但这只会把问题移开。如果要在自己的库中创建类实例,那么仍然存在相同的问题--您的库是直接从web.config读取的。

更好的解决方案是使用依赖注入来指定类所依赖的所有值。)在这篇文章中,这是一个很重要的话题。下面是一个使用Castle的依赖注入的起始示例

使用它,您可以指定连接字符串的来源,如下所示:

代码语言:javascript
运行
复制
container.Register(
    Component.For<ReadsSomethingFromSql>()
        .DependsOn(Dependency.OnValue("connectionString",
            ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString))
    );

如果它不仅仅是一个连接字符串,可能是类需要的许多设置,那么您可以创建一个接口,如下所示:

代码语言:javascript
运行
复制
public interface ISettings
{
    string Setting1 { get; }
    int SomeOtherSetting { get; }
}

并将其放入类的构造函数中,就像上面的连接字符串一样。

代码语言:javascript
运行
复制
public class MyClass
{
    private readonly ISettings settings;

    public MyClass(ISettings settings)
    {
        _settings = settings;
    }

这样,类就会引用_settings,它是ISettings的一个实例,但它并不“知道”实现是什么。

然后,您可以创建一个实现ISettings的类,它从配置中获取值,如下所示:

代码语言:javascript
运行
复制
public class Settings : ISettings
{
    public string Setting1 { get { return ConfigurationManager.AppSettings["MyClass:Setting1"]; } }
    public int SomeOtherSetting {
        get
        {
            return Int32.Parse(ConfigurationManager.AppSettings["MyClass:SomeOtherSettings"]);
        }
    } }
}

这将解决您的类的问题取决于配置。它不依赖于配置。这将取决于ISettings

使用温莎,您的应用程序会像这样配置它:

代码语言:javascript
运行
复制
container.Register(Component.For<ISettings,Settings>());

我并不是真的用这些粗略的例子来做依赖注入正义。但我用同样的问题开始了同样的道路。依赖注入是解决问题的方法,并且在许多其他方面也会使您受益。

更新:您提到的不需要修改类的使用者的。我想我看到了问题的一部分-你的Core1.0应用程序不会有web.config。

你可以妥协。修改类的构造函数并使参数成为可选参数。这样,在编写新的消费者时,可以使用依赖项注入。老消费者可以像现在这样工作,像这样:

代码语言:javascript
运行
复制
public class ReadsSomethingFromSql
{
    private readonly string _connectionString;

    public ReadsSomethingFromSql(string connectionString = null)
    {
        _connectionString = connectionString
            ?? ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
    }
票数 1
EN

Stack Overflow用户

发布于 2016-03-05 23:42:07

我不完全确定你想要什么:

1)库配置数据需要位于主项目的配置文件中? 2)库需要将所有其他项目的配置数据嵌入到自己的配置中?

如果#1,如果您需要什么,那么它就像使用您的配置文件一样容易。我目前正在生产,使用4个库的4个the应用程序,其中2个在使用它的项目上有自定义配置。我使用appSettings webconfig部分。库将使用以下方法读取该配置文件:

代码语言:javascript
运行
复制
ConfigurationManager.AppSettings["<CONFIG KEY HERE>"]

如果是#2,那么它或多或少是一样的。只需为库的所有内容编写自定义配置,然后与所有数据一起发布即可。但我会做第一名的。

如果我把你的问题搞错了,那就对不起!如果你能更详细地解释你的情况,我会很乐意帮你的。

作为一个附带的问题,对于这些不同的系统,我预期还有什么其他的问题吗?

这是坏的,坏的,坏的!我只是有个相关的问题。查看我的帖子:Windows通用应用程序适合我吗?- UI迁移

拥有框架2和4将给您带来问题,同时也会混合平台和最新的microsoft技术,比如aspnet核心和UWA。

我会检查两次并做一些广泛的测试,然后在任何时候编写一些不起作用的代码。

干杯

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35821065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档