C# 基于字符串值按属性获取正确的类

C# 基于字符串值按属性获取正确的类,c#,asp.net,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc 5,在这个ASP.net MVC5应用程序中,有一个文件夹Templates,其中包含一组不同的类,这些类都具有不同的TemplateName属性。此方法的第一部分需要找到TemplateName与传入字符串匹配的类。然后我需要创建一个模板匹配的实例。我对C语言中的属性非常陌生,因此非常感谢您的帮助。我主要需要知道如何访问程序中的类文件夹来查看它 在C语言中,您试图做的就是所谓的反射 下面是指向另一个答案的链接,该答案显示了如何获取名称空间中的所有类。我假设物理文件夹意味着对文件夹中包含的类使用唯一

在这个ASP.net MVC5应用程序中,有一个文件夹Templates,其中包含一组不同的类,这些类都具有不同的TemplateName属性。此方法的第一部分需要找到TemplateName与传入字符串匹配的类。然后我需要创建一个模板匹配的实例。我对C语言中的属性非常陌生,因此非常感谢您的帮助。我主要需要知道如何访问程序中的类文件夹来查看它

在C语言中,您试图做的就是所谓的反射

下面是指向另一个答案的链接,该答案显示了如何获取名称空间中的所有类。我假设物理文件夹意味着对文件夹中包含的类使用唯一的名称空间

**顺便说一句,您应该查看反射性能,看看它在您的情况下是否有意义。您可能希望改用factory模式

这将起作用:

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);
                }
            }
        }