静态通用构建器

时间:2018-03-21 08:45:06

标签: c# .net .net-core

我试图为我的班级实现类似Asp Net Core的静态构建器。这就是我正在谈论的内容。在BuildWebHost方法WebHostIWebHostBuilder中的Asp Net Core应用程序创建public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build();

UseStartup<Startup>()

我对Startup方法感兴趣,所以我想知道这种方法如何理解&#39;它必须使用什么public static IWebHostBuilder UseStartup<TStartup>(this IWebHostBuilder hostBuilder) where TStartup : class; 类? 此方法的签名是:

ICleaner

在我的应用程序中,我想使用类似的方法,例如这里我有一个简单的空接口Cleaner,它由一些CleanerBuilder类实现,然后我有Cleaner class,负责向List添加适当的Build类,配置它们并在public class CleanerBuilder { private List<ICleaner> _activeCleaners { get; set; } private CleanerBuilder() { } public static CleanerBuilder CreateDefaultBuilder(string[] args) { var cleanerBuilder = new CleanerBuilder(); /* * ... */ return cleanerBuilder; } public CleanerBuilder UseCleaner<ICleaner>() { _activeCleaners.Add(???); return this; } public void Build() { foreach(var cleaner in _activeCleaners) { cleaner.Run(); } } } 方法之后运行它们。这是我的CleanerBuilder课程。这是我的CleanerBuilder课程:

CleanerBuilder.CreateDefaultBuilder(args)
    .UseCleaner<TempCleaner>()
    .Build();

用法是:

UseCleaner

现在我不知道在ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>(); postParameters.add(new BasicNameValuePair("username", username)); post.setEntity(new UrlEncodedFormEntity(postParameters, Consts.UTF_8)); 方法中该怎么做。

3 个答案:

答案 0 :(得分:1)

最简单的实现可能是这样的:

    public CleanerBuilder UseCleaner<TCleaner>() where TCleaner : ICleaner, class, new
    {
        _activeCleaners.Add(new TCleaner());

        return this;
    }

然而,你真的没有在这里获得:

public CleanerBuilder UseCleaner(ICleaner cleaner)
{
    _activeCleaners.Add(cleaner);

    return this;
}

在这个简单版本中,通用版本受到更多限制,因为 具有空构造函数。不酷,也许它没有。微软用它做的StartUp是将它连接到它的依赖注入容器并尝试从那里构建它。这解决了构造函数参数的问题。

如果您已将Visual Studio配置为下载源,只需按UseStartup方法上的F12即可查看它们在那里执行的操作。或者,您可以在relevant JMeter Properties

中查找

答案 1 :(得分:1)

WebHostBuilder类使用反射来创建启动类的实例。如果你想做类似的事情,那么你的List实现需要存储一个Type

private List<Type> _activeCleaners { get; set; }

然后在你的Add方法中你可以使用:

public CleanerBuilder UseCleaner<TCleaner>() where TCleaner : ICleaner, class, new
{
    _activeCleaners.Add(typeof(TCleaner));

    return this;
}

但在这种情况下,您需要研究如何在需要时创建ICleaner实例。我认为,在这种情况下,nvoigt的回答可能对你更好。

答案 2 :(得分:1)

您要实现的目标是builder pattern。构建器的工作是收集构建类型的依赖项,需求和参数。

UseCleaner通常不会或者必须做很多事情,只是将ICleaner的类型存储在列表中以便稍后进行实例化,这可能是因为用户调用了{{1} } 方法。这里的最简单要求Build有一个无参数构造函数。

ICleaner

您也可以将private readonly List<Type> _activeCleaners; public CleanerBuilder UseCleaner<ICleaner>() where ICleaner : class, new() // We now require that ICleaners has a parameterless constructor { _activeCleaners.Add(typeof(ICleaner)); return this; } public Cleaner Build() { // Lazily create instances of the cleaners var cleaners = _activeCleaners.Select(Activator.CreateInstance); // Pass enumerator for instantiated cleaners to the object return new Cleaner(cleaners); } 与参数一起使用,或者如果您不想要无参数构造函数,则可以使用依赖注入容器。