1

Take the following class hierarchy:

  • Client
    • FacebookClient
    • PinterestClient
    • TwitterClient

Each client must define a value for an enum property named ClientType (string property Url in the original version of this question; hence the accepted answer). ClientFactory should then be able to instantiate by client type.

ClientFactory.Create(ClientType.Facebook);

ClientType could be a static property for each subtype, and then subtypes could be selected by its value in the factory:

// Create array of possible client subtypes
Type[] clients = new[] { typeof(FacebookClient), typeof(PinterestClient), typeof(TwitterClient) };

// Select subtype with URL that matches one passed to factory
Type client = clients.SingleOrDefault(c => clientType == (Client)c.GetProperty("ClientType").GetValue(null));
return (Client)Activator.CreateInstance(client, parameters);

However, since static members can't be abstract, I'm not sure of a way to ensure that ClientType is set, and there are dozens of subtypes.

Is there a way to force ClientType to be set? Would another way of doing this (e.g., a switch statement) be a better option?

  • 2
    I really don't like your approach. Why don't you just use a simple factory method passing the URL to it and instantiating the desired implementation based on the value of the parameter? Why complicate it so much? – Andy Feb 15 '16 at 13:46
  • I'm definitely open to that. My thought was that since Url is already defined/has to be used elsewhere, it would be better to select on it versus redefining it in a switch statement. I haven't worked a whole lot with factories, so I'm sure I'm missing things here. I appreciate the help. – Eric Eskildsen Feb 15 '16 at 13:54
  • Also, I find it strange that, at runtime, you know the service URL but not the service type. In other words, I find it odd that your factory selects the service type by URL. Shouldn't you just have factory.CreateFacebookClient() etc... ? – MetaFight Feb 16 '16 at 14:34
  • @MetaFight I've edited the question to better reflect the actual usage. ClientType is an enum that users can choose multiple values from on the application's front end. These values are then passed to the factory, which creates the appropriate instances. The caller can then loop through them and call implementations of abstract methods defined in the base Client class that apply to all subtypes, like PostMessage. – Eric Eskildsen Feb 16 '16 at 21:55
6

It looks like you're combining a factory with a service-locator.

Anyway, you can build a Dictionary<string,Type> instead of the array of types and querying them for which Url they respond to. This is even more flexible, because then you can allow your application to register new Clients at runtime, if that ever becomes necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.