具有自己的配置类

时间:2017-05-10 14:53:17

标签: c# class inner-classes partial-classes

我有几个控制器类,它们使用自己的配置类来设置控制器类的行为。

我有控制器解析器,它按名称选择所需的控制器。

现在我想要另一个解析器将控制器类与其各自的配置类绑定。

我现在拥有的是嵌套在与控制器类同名的部分类中的配置类,因此解析器可以明确地确定配置类,但我对这种怪异的solotion不是很满意,因为仅包含部分类嵌套配置类必须与控制器类具有相同的命名空间,因为它的名称与该类物理上所在的文件夹不一致,因为控制器类位于“Controller”文件夹中,并且它们的命名空间是“Something.Controller”。 “和配置类在”配置“文件夹中,但它们的命名空间也必须是”Something.Controller“。

//Path: .\Controller
namespace Something.Controller
{
    public partial class MyController : IController
    {
    }
}

//Path: .\Configuration
namespace Something.Controller
{
    public partial class MyController
    {
        public class MyControllerConfiguration : IConfiguration
        {
        }
    }
}

解析器(没有类型验证,因为它之前已经完成,并且可以传递给这些方法的唯一类型已经实现IController):

public class Resolver
{
    public IController GetController(Type controllerType)
    {
        return (IController)Activator.CreateInstance(controllerType);
    }
    public IConfiguration GetControllerConfiguration(Type controllerType)
    {
        var configurationType = controllerType.GetNestedTypes().FirstOrDefault(t => typeof(IConfiguration).IsAssignableFrom(t));
        if (configurationType != null)
            return (IConfiguration)Activator.CreateInstance(configurationType);
        else
            return null;
    }
}

那么如何将控制器类与其配置类结合起来比在各自的控制器类中嵌套配置类更清晰?

编辑:

下面是一些使用示例:

让我们想象一下,我有两个控制器。每个人都有自己的配置。现在我想让用户选择要使用的控制器,然后从相应的配置类显示用户属性集。当然,我可以创建控制器实例,在用户设置应用程序配置时公开其配置,但我不相信这是一个好主意。

2 个答案:

答案 0 :(得分:0)

这个建议建立在Dependency Inversion的原则之上。 (帖子中的例子实际上与这个确切的问题密切相关。)

这个想法是你的控制器不应该负责确定配置值的来源。它应该依赖于抽象,就像接口一样。

我要做的第一件事就是将您的设置分成他们自己的界面,例如:(这不是抄袭 - 这是我的博文。)

public interface IConfiguration
{
    string SomeSetting { get; }
    int OtherSetting { get; }
}

然后在你的控制器类中,执行以下操作:

public class MyController
{
    private readonly IConfiguration _configuration;

    public MyController(IConfiguration configuration)
    {
        _configuration = configuration;
    }
}

现在,从控制器本身的角度来看,工作已经完成。构造函数中需要IConfiguration,因此如果不提供实现MyController某些,则无法创建IConfiguration的实例。

这很有用,因为它鼓励您完成编写控制器而不解决配置设置的来源问题。你推迟了。您可以完成手头的任务,然后决定如何实施IConfiguration。它可以防止琐碎的任务从更重要的任务中偏离你。

按照设计,MyController永远不会知道实现是什么。它并不关心。它只取决于界面。您只需使用MyController的不同实现,即可更改设置的来源而无需更改IConfiguration。如果你想为MyController编写单元测试并使用不同的配置设置进行测试,你可以简单地写一下" mocked"具有硬编码值的IConfiguration的实现。

这就留下了IConfiguration如何传递给构造函数的问题。这通常(或通常)使用Unity,Autofac或Windsor等依赖注入容器完成。如果您正在使用ASP.NET Core,那么它就是一个内置容器。 (我猜这是一个MVC控制器,但也许它不是 - 它并不重要。)

要查找有关如何配置应用程序以使用依赖项注入容器的说明,请使用Google所用技术的名称+"依赖注入",类似于" ASP.NET MVC依赖注入。"或者如果你提到你正在使用的东西,我可以给你指一篇文章。

依赖注入并不是一个灵丹妙药,但对于任何复杂的应用程序,包括MVC应用程序,它都非常有用。我发现这是理解和应用其他原则以及学习编写单元测试的一步。它也帮助我避免陷入困境。如果我写的课程需要依赖别的东西,那么我只需为该依赖编写一个界面,并继续处理我正在研究的课程。然后我可以回过头来决定如何实现这种依赖。

答案 1 :(得分:0)

有很多方法可以做到这一点。

例如,在Spring框架中,配置可以在单独的XML文件中完成,该文件通过" set"填充每个控制器属性。方法

另一种常见方法是让Controller从某种类型的单例PropertyManager查找其属性,该单例可以包含文件,数据库或内存实现。

问题是,您是否真的需要为每个控制器或控制器提供单独的配置类,还可以具有从单独的配置存储库获取其配置的逻辑,但同时不关心该存储库如何读取/写入其配置