C# 基于字符串值按属性获取正确的类
在这个ASP.net MVC5应用程序中,有一个文件夹Templates,其中包含一组不同的类,这些类都具有不同的TemplateName属性。此方法的第一部分需要找到TemplateName与传入字符串匹配的类。然后我需要创建一个模板匹配的实例。我对C语言中的属性非常陌生,因此非常感谢您的帮助。我主要需要知道如何访问程序中的类文件夹来查看它 在C语言中,您试图做的就是所谓的反射 下面是指向另一个答案的链接,该答案显示了如何获取名称空间中的所有类。我假设物理文件夹意味着对文件夹中包含的类使用唯一的名称空间 **顺便说一句,您应该查看反射性能,看看它在您的情况下是否有意义。您可能希望改用factory模式 这将起作用:C# 基于字符串值按属性获取正确的类,c#,asp.net,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc 5,在这个ASP.net MVC5应用程序中,有一个文件夹Templates,其中包含一组不同的类,这些类都具有不同的TemplateName属性。此方法的第一部分需要找到TemplateName与传入字符串匹配的类。然后我需要创建一个模板匹配的实例。我对C语言中的属性非常陌生,因此非常感谢您的帮助。我主要需要知道如何访问程序中的类文件夹来查看它 在C语言中,您试图做的就是所谓的反射 下面是指向另一个答案的链接,该答案显示了如何获取名称空间中的所有类。我假设物理文件夹意味着对文件夹中包含的类使用唯一
public ActionResult AddComplianceForm(string TemplateName)
{
}
不要只使用反射
处理这种情况的典型方法是反射和运行时类型发现/绑定。然而,在这种情况下,这可能是一个糟糕的起点。模板名作为操作参数传入,可能是通过绑定到请求字符串中的值传入的,您不希望c代码实例化从web传入的任何类!!!这将是一个严重的安全问题,被称为安全问题
创建一个列表
为了降低风险,正确的方法是将论点与实际情况对照。如果我们已经有了一个白名单,那么我们可以将名单中的每个项目与一个lambda表达式相关联,该表达式返回您想要的对象
public class HomeController : Controller
{
public ActionResult AddComplianceForm(string TemplateName)
{
Assembly assembly = Assembly.Load("Testy20161006"); //assembly name
Type t = assembly.GetType("Testy20161006.Templates." + TemplateName); //namespace + class name
Object obj = (Object)Activator.CreateInstance(t);
return View();
}
这将自动遍历为应用程序加载的所有类型,并找到具有TemplateAttribute的类型。操作参数中只允许使用这些类型
注:
在这些示例中,我假设您的所有模板都继承自BaseTemplate,但如果它们没有共同的祖先,我不建议您使用object
在这些示例中,我存储列表并在控制器中实现代码,但是如果要使用结构良好的代码,则应该考虑将所有这些东西移到某种工厂类中,然后从控制器中传递字符串。
class MyController
{
static private readonly Dictionary<string,Func<BaseTemplate>> _templateList = new Dictionary<string,Func<BaseTemplate>>();
static MyController()
{
_templateList.Add("ATemplate", () => return new ATemplate());
_templateList.Add("SomeOtherTemplate", () => return new SomeOtherTemplate());
_templateList.Add("JustOneMore", () => return new JustOneMore());
}
public ActionResult AddComplianceForm(string TemplateName)
{
BaseTemplate template;
try
{
template = _templateList[TemplateName]();
}
catch (KeyNotFoundException exception)
{
RedirectToAction("MyController", "InvalidTemplateError");
}
DoSomethingWithTemplate(template);
}
}
foreach (Assembly b in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type t in b.GetTypes())
{
var a = Attribute.GetCustomAttribute(t, typeof(TemplateAttribute));
if (a != null)
{
var localType = t; //Avoid closure on loop variable
_templateList.Add(t.Name, () => Activator.CreateInstance(localType) as BaseTemplate);
}
}
}