最好的方式来动态地创建类,而不是使用一个开关块 [英] Best way to dynamically create classes instead of using a switch block
问题描述
目前我已经在实现接口的类来实现我的VaryByCustom是功能 IOutputCacheVaryByCustom
Currently I have my VaryByCustom functionality implemented in classes that implement an interface IOutputCacheVaryByCustom
public interface IOutputCacheVaryByCustom
{
string CacheKey { get; }
HttpContext Context { get; }
}
一个类实现这个接口有一些约定类的名称会是OutputCacheVaryBy_的 __ 里的空白是从VaryByCustom是属性传递页面上的价值。另一个约定是这方面将通过构造器注入来设定。
A class implementing this interface has a few conventions the name of the class will be "OutputCacheVaryBy___" where the blank is the value that is passed in from the varyByCustom property on pages. The other convention is that Context will be set through constructor injection.
目前,我立足这一关枚举和类似于
Currently I'm basing this off an enum and a switch statement similar to
public override string GetVaryByCustomString(HttpContext context,
string varyByCustomTypeArg)
{
//for a POST request (postback) force to return back a non cached output
if (context.Request.RequestType.Equals("POST"))
{
return "post" + DateTime.Now.Ticks;
}
var varyByCustomType = EnumerationParser.Parse<VaryByCustomType?>
(varyByCustomTypeArg).GetValueOrDefault();
IOutputCacheVaryByCustom varyByCustom;
switch (varyByCustomType)
{
case VaryByCustomType.IsAuthenticated:
varyByCustom = new OutputCacheVaryByIsAuthenticated(context);
break;
case VaryByCustomType.Roles:
varyByCustom = new OutputCacheVaryByRoles(context);
break;
default:
throw new ArgumentOutOfRangeException("varyByCustomTypeArg");
}
return context.Request.Url.Scheme + varyByCustom.CacheKey;
}
因为我总是知道类将是 OutputCacheVaryBy + varyByCustomTypeArg
和唯一的构造函数参数将是背景
我意识到我可以绕过需要这个荣耀的if else块可能只是实例我自己的目标与激活
。
Since I always know that the class will be OutputCacheVaryBy + varyByCustomTypeArg
and the only constructor argument will be context
I realized I could bypass needing this glorified if else block and could just instantiate my own object with Activator
.
通过这个虽这么说,反思是不是我的强项,我知道,激活
基本相对缓慢静态创作和其他方法来生成对象。是否有任何理由为什么我要这个当前的代码坚持还是应该使用激活
或类似的方法来创建我的对象?
With this being said, reflection is not my strong suit and I know that Activator
is substantially slow comparatively to static creation and other ways to generate objects. Is there any reason why I should stick with this current code or should I use Activator
or a similar way to create my object?
我已经看到了博客的 http://www.smelser.net/blog/post/2010/03/05/When-Activator-is-just-to-slow.aspx ,但我真的不知道如何做到这一点适用,因为我与类型在运行时不静牛逼的工作。
I've seen the blog http://www.smelser.net/blog/post/2010/03/05/When-Activator-is-just-to-slow.aspx but I'm not really sure how this would apply since I'm working with types at runtime not static T.
推荐答案
您并不需要使用反射,因为它是一组相当有限的可能值。然而,你可以做这样的事情。
You don't really need to use reflection since it's a rather limited set of possible values. You could however do something like this
internal class Factory<T,Arg>
{
Dictionary<string,Func<Arg.T>> _creators;
public Factory(IDictionary<string,Func<Arg,T>> creators)
{
_creators = creators;
}
}
和
and substitute your creation logic with
_factory[varyByCustomTypeArg](context);
这不是一样快的开关,但会将建设和使用很好地单独
it's not as fast as a switch but it keeps construction and use nicely seperate
这篇关于最好的方式来动态地创建类,而不是使用一个开关块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!