简体   繁体   中英

Right way to choose and instantiate C# class depends on string value?

I have base class

public abstract class HostBehavior : SiteHost
{
    public abstract List<string> ParseNews(string url);
}

And many derived classes...

What is the best way to choose which constructor should be called depends on url?

Right now I have long sequence of "if else" statements like this example:

public static HostBehavior ResolveHost(string url)
{
    if (uri.IndexOf("stackoverflow.com") > 0)
    {
        return new stackoverflowBehavior();
    }
    else if(uri.IndexOf("google.com") > 0)
    {
        return new googleBehavior();
    }
    // and so on...
    else
    {
        throw new Exception...
    }
}

I decided to give each class a custom attribute

[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct)]
public class HostAttribute : System.Attribute
{
    public string name;

    public HostAttribute(string name)
    {
        this.name = name;
    }
}

So my classes looks like

[Host("stackoverflow.com")]
public class stackoverflowBehavior : HostBehavior
{
//...
}

Now I can get all classes from assembly's folder|namespace

Assembly asm = Assembly.GetExecutingAssembly();
Type[] hostTypes = asm.GetTypes()
            .Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"Hosts"))
            .ToArray();

Finally I need to find type with HostAttribute same as incoming url.Host

foreach(Type t in hostTypes)
{
     HostAttribute attribute = (HostAttribute)Attribute.GetCustomAttribute(t, typeof(HostAttribute));
     if (attribute.name ==  url.Host)
         return (HostBehavior)Activator.CreateInstance(t);
}

I want to thank everyone quotes, especially to Ed Plunkett.

查看您在查询中解释的方案,看来您可以使用工厂模式来满足您的要求。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM