The problem

I have a class hierarchy with a common base class Action. Multiple classes inherit and extend the base class:

There are more classes in the hierarchy. Additionally, any app using the class hierarchy can add their own Action implementation as needed.

I want to automate the creation of derived classes instances’, based on string identifier.

Also, I want any app using the class hierarchy to use the solution out of the box.

Something like

Action = Solution.Create (“ActionCopyFile”);

So, what’s the solution?

It’s a design pattern named The Factory Method.

Declaring A Generic C# Factory

The GenericFactory class will have:

  • one generic argument TBase (the base class of the hierarchy)
  • a dictionary to store associations between a string ID and a Creator method (mCreators)
  • a register method to associate an ID with a Creator (Register)
  • a create method to call the Creator associated with an ID (Create)

This way, we can use the generic factory with multiple class hierarchies.

Generic C# Factory - Declare

A Creator is a delegate that will match any method returning a class instance derived from TBase.

We’re also making all class members and methods static.

This way, you won’t have instantiate the factory class every time you want to use it.

The Register Method

Simply adds a new entry to the dictionary.

Some additional checks are required before adding the pair:

  • prevent an empty ID
  • prevent and empty creator
  • prevent duplicate entries

Generic C# Factory - Register Method

Using the method goes something like GenericFactory<string>.Register(“actionCopy”, () => new ActionCopyFile());

I’ve used a lamba expression as the 2nd argument to simply create a new instance of the ActionCopyFile;

But it can be any other method that matches the Creator delegate signature.

The Create Method Call

This will have to fetch the creator associated with and ID and invoke it.

Try to get the value and invoke it. If not, an exception will be thrown.

Generic C# Factory - calling Create()

Better readability with global usings

I want an easier way to access the factory’s functionality, without having to write an essay every time I want to access a method.

Enter global usings.

I’ve added a GlobalUsings.cs file to the project, and I’ve put all aliases in there.

C# Factory - Global Usings

It’s much faster to write FileActionFactory.Create, instead of RealityFrameworks.GenericFactory<RealityFrameworks.Actions.Action<string>>;

Don’t you agree? I’m much happier with the shorthand notation, thank you very much.

The only fallback with the global using’s method is that aliases are visible only within the current assembly.

If I want to use the aliases in a different assembly, you must copy the GlobalUsings.cs file to your other assembly.

Registering multiple creators

In my main app, I’ve created a method to register all creators, both for the predefined Action’s and for the new ones the app implements.

  • ActionAddYaml
  • ActionUpdateYaml<FrontMatterData>
  • ActionRemoveYaml
  • … and so on

I’m using the GenericFactory class for both Conditions and Actions, and also for Editors, as you can see below:

Generic C# Factory - Registering Creators

Using the Create method

And this is how you use the Create method with a generic factory.

Generic C# Factory - Calling Create Method

Simply pass an identifier to the Create method of the factory of choices.

Full Code

Download the full generic factory code here.

By devapps

Leave a Reply

Your email address will not be published. Required fields are marked *