Factory With Self-Registering Types 
Tags: cpp, programming, patterns
Published: 2018-02-19 10:37:56

---
title: Factory With Self-Registering Types 
published: true
description: Factories usually know all the types upfront. But we might invert that rule and allow types to do a self-registration. Is that useful?
tags: cpp, programming, patterns
---


[![Factory with self registering types](https://4.bp.blogspot.com/-XPaDFytNFKU/WnYKZiBIazI/AAAAAAAADQs/GxBzyQlY1s8v2KcKTfnlAk2GFlA3xqSLgCLcBGAs/s1600/factoryself.png)](http://www.bfilipek.com/2018/02/factory-selfregister.html)

Writing a factory method might be simple:

```cpp
unique_ptr<IType> create(name) {
    if (name == "Abc") return make_unique<AbcType>();
    if (name == "Xyz") return make_unique<XyzType>();
    if (...) return ...
    
    return nullptr;
}
```
Just one switch/if and then after a match you return a proper type.

But what if we don't know all the types and names upfront? Or when we'd like to make such factory more generic? 

Let's see how classes can register themselves in a factory and what are the examples where it's used.

**One note:** this article comes from my blog: [Bartek's coding blog: Factory With Self-Registering Types](http://www.bfilipek.com/2018/02/factory-selfregister.html).


## Intro

The code shown as the example at the beginning of this text is not wrong when you have a relatively simple application. For example, in my [experiments with pimpl](http://www.bfilipek.com/2018/01/pimpl-interface.html), my first version of the code contained:

```cpp
static unique_ptr<ICompressionMethod> 
Create(const string& fileName)
{
    auto extension = GetExtension(filename);
    if (extension == "zip")
        return make_unique<ZipCompression>();
    else if (extension = "bz")
        return make_unique<BZCompression>();

    return nullptr;
}
```

In the above code, I wanted to create `ZipCompression` or `BZCompression` based on the extensions of the filename.

That straightforward solution worked for me for a while. Still, if you want to go further with the evolution of the application you might struggle with the following issues:

* Each time you write a new class, and you want to include it in the factory you have to add another if in the `Create()` method. Easy to forget in a complex system.
* All the types must be known to the factory
* In `Create()` we arbitrarily used strings to represent types. Such representation is only visible in that single method. What if you'd like to use it somewhere else? Strings might be easily misspelt, especially if you have several places where they are compared.

So all in all, we get strong dependency between the factory and the classes.

But what if classes could register themselves? Would that help?

* The factory would just do its job: create new objects based on some matching.
* If you write a new class there's no need to change parts of the factory class. Such class would register automatically.

It sounds like an excellent idea. 

## A practical example

To give you more motivation I'd like to show one real-life example:

### Google Test

When you use Google Test library, and you write:

```cpp
TEST(MyModule, InitTest)
{
}
```

Behind this single `TEST` macro a lot of things happen!

For starters your test is expanded into a separate class - so each test is a new class. 

But then, there's a problem: you have all the tests, so how the test runner knows about them? 

It's the same problem were' trying to solve in this post. The classes need to be registered.

Have a look at this code: from [googletest/.../gtest-internal.h](https://github.com/google/googletest/blob/ea31cb15f0c2ab9f5f5b18e82311eb522989d747/googletest/include/gtest/internal/gtest-internal.h#L1218):

```
// (some parts of the code cut out)
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public parent_class \
{\
  virtual void TestBody();\
  static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
};\
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
  ::test_info_ =\
    ::testing::internal::MakeAndRegisterTestInfo(\
        #test_case_name, #test_name, NULL, NULL, \
        new ::testing::internal::TestFactoryImpl<\
            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
```

I cut some parts of the code to make it shorter, but basically `GTEST_TEST_` is used in `TEST` macro and this will expand to a new class. In the lower section, you might see a name `MakeAndRegisterTestInfo`. So here's the place where the class registers!

After the registration, the runner knows all the existing tests and can invoke them.

When I was implementing a custom testing framework for one of my projects I went for a similar approach. After my test classes were registered, I could filter them, show their info and of course be able to execute the test suits.

I believe other testing frameworks might use a similar technique.

### Flexibility

My previous example was related to unknown types: for tests, you know them at compile time, but it would be hard to list them in one method create. 

Still, such self-registration is useful for flexibility and scalability. Even for my two classes: `BZCompression` and `ZipCompression`.

Now when I'd like to add a third compression method, I just have to write a new class, and the factory will know about it - without much of intervention in the factory code.

Ok, ok... we've discussed some examples, but you probably want to see the details!

So let's move to the actual implementation.

## Self-registration

What do we need?

* Some Interface - we'd like to create classes that are derived from one interface. It's the same requirement as a "normal" factory method.
* Factory class that also holds a map of available types
* A proxy that will be used to create a given class. The factory doesn't know how to create a given type now, so we have to provide some proxy class to do it.

For the interface we can use `ICompressionMethod`:

```cpp
class ICompressionMethod
{
public:
    ICompressionMethod() = default;
    virtual ~ICompressionMethod() = default;

    virtual void Compress() = 0;
};
```

And then the factory:

```cpp
class CompressionMethodFactory
{
public:
    using TCreateMethod = unique_ptr<ICompressionMethod>(*)();

public:
    CompressionMethodFactory() = delete;

    static bool Register(const string name, TCreateMethod funcCreate);
    
    static unique_ptr<ICompressionMethod> Create(const string& name);

private:
    static map<string, TCreateMethod> s_methods;
};
```

The factory holds the map of registered types. The main point here is that the factory uses now some method (`TCreateMethod`) to create the desired type (this is our proxy). The name of a type and that creation method must be initialized in a different place.

The implementation of such factory:

```cpp
map<string, TCreateMethod> CompressionMethodFactory::s_methods;

bool CompressionMethodFactory::Register(const string name, 
                                        TCreateMethod& funcCreate)
{
    if (auto it = s_methods.find(name); it == s_methods.end())
    { // C++17 init-if ^^
        s_methods[name] = funcCreate;
        return true;
    }
    return false;
}

unique_ptr<ICompressionMethod> 
CompressionMethodFactory::Create(const string& name)
{
    if (auto it = s_methods.find(name); it != s_methods.end()) 
        return it->second(); // call the createFunc

    return nullptr;
}
```

Now we can implement a derived class from `ICompressionMethod` that will register in the factory:

```cpp
class ZipCompression : public ICompressionMethod
{
public:
    virtual void Compress() override;
    
    static unique_ptr<ICompressionMethod> CreateMethod() { 
        return smake_unique<ZipCompression>();
    }
    static std::string GetFactoryName() { return "ZIP"; }

private:
    static bool s_registered;
};
```

The downside of self-registration is that there's a bit more work for a class. As you can see we have to have a static `CreateMethod` defined.

To register such class all we have to do is to define `s_registered`:

```cpp
bool ZipCompression::s_registered =
  CompressionMethodFactory::Register(ZipCompression::GetFactoryName(),   
                                     ZipCompression::CreateMethod);

```

The basic idea for this mechanism is that we rely on static variables. They will be initialized before `main()` is called. 

But can we be sure that all of the code is executed, and all the classes are registered? `s_registered` is not used anywhere later, so maybe it could be optimized and removed? And what about the order of initialization?

### Static var initialization

We might run into two problems:

#### Order of static variables initialization:

It's called *"static initialization order fiasco"* - it's a problem where one static variable depends on another static variable. Like `static int a = b + 1` (where `b` is also static). You cannot be sure `b` will be initialized before `a`. Bear in mind that such variables might be in a different compilation unit.
 
Fortunately, for us, it doesn't matter. We might end up with a different order of elements in the factory container, but each name/type is not dependent on other already registered types. 

But what about the first insertion? Can we be sure that the map is created and ready for use?

To be certain I've even asked a question at SO:
[C++ static initialization order: adding into a map - Stack Overflow](https://stackoverflow.com/questions/48578226/c-static-initialization-order-adding-into-a-map)

Our map is defined as follows:

```cpp
map<string, TCreateMethod> CompressionMethodFactory::s_methods;
```

And that falls into the category of [Zero initialization](http://en.cppreference.com/w/cpp/language/zero_initialization). Later, the dynamic initialization happens - in our case, it means all `s_registered` variables are inited.

So it seems we're safe here.
 
 You can read more about it at [isocpp FAQ](https://isocpp.org/wiki/faq/ctors#static-init-order) and at [cppreference - Initialization](http://en.cppreference.com/w/cpp/language/initialization#Non-local_variables).

#### Can `s_registered` be eliminated?

Fortunately, we're also on the safe side:

From the latest draft of C++: [n4713.pdf](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf) [basic.stc.static], point 2:

> variable with static storage duration has initialization or a destructor with side effects; it shall not be eliminated even if it appears to be unused.

So the compiler won't optimize such variable.

Although this might happen when we use some templated version... but more on that later.


Update: and read what can happen when your symbols comes from a static library:  [my newest post: Static Variables Initialization in a Static Library, Example](http://www.bfilipek.com/2018/02/static-vars-static-lib.html)

## Extensions

All in all, it seems that our code should work! :)

For now, I've only shown a basic version, and we can think about some updates:

### Proxy classes

In our example, I've used only a map that holds `<name, TCreateMethod` - this works because all we need is a way to create the object.

We can extend this and use a "full" proxy class that will serve as "meta" object for the target type.

In my final app code I have the following type:

```cpp
struct CompressionMethodInfo
{
    using TCreateMethod = std::unique_ptr<ICompressionMethod>(*)();
    TCreateMethod m_CreateFunc;
    string m_Description;
};
```

Beside the creation function, I've added `m_Description`. This addition enables to have a useful description of the compression method. I can then show all that information to the user without the need to create real compression methods.

The factory class is now using

```cpp
static map<string, CompressionMethodInfo> s_methods;
```

And when registering the class, I need to pass the info object, not just the creation method.

```cpp
bool ZipCompression::s_registered =
  CompressionMethodFactory::Register(
      ZipCompression::GetFactoryName(), 
      { ZipCompression::CreateMethod, 
        "Zip compression using deflate approach" 
      });
```

### Templates

As I mentioned the downside of self-registration is that each class need some additional code. Maybe we can pack it in some `RegisterHelper<T>` template?

Here's some code (with just creation method, not with the full info proxy class):

```cpp
template <typename T>
class RegisteredInFactory
{
protected:
    static bool s_bRegistered;
};

template <typename T>
bool RegisteredInFactory<T>::s_bRegistered = 
CompressionMethodFactory::Register(T::GetFactoryName(), T::CreateMethod);
```

The helper template class wraps `s_bRegistered` static variable and it registers it in the factory. So now, a class you want to register just have to provide `T::GetFactoryName` and `T::CreateMethod`:

```cpp
class ZipCompression : public ICompressionMethod, 
                       public RegisteredInFactory<ZipCompression>
{
public:
    virtual void Compress() override { /*s_bRegistered;*/ }

    static unique_ptr<ICompressionMethod> CreateMethod() { ... }
    static std::string GetFactoryName() { return "ZIP"; }
};
```

Looks good... right?

But when you run it the class is not being registered!

Have a look at [this code @coliru](http://coliru.stacked-crooked.com/a/1a203e86a8898a59).

But if you uncomment `/*s_bRegistered*/` from `void Compress()` the registration works fine.

Why is that?

It seems that although `s_bRegistered` is also a static variable, it's inside a template. And templates are instantiated only when they are used ([see odr-use @stackoverlow](https://stackoverflow.com/questions/19630570/what-does-it-mean-to-odr-use-something)). If the variable is not used anywhere the compiler can remove it...

Another topic that's worth a separate discussion.

So all in all, we have to be smarter with the templated helper. I'll have to leave it for now.

### Not using strings a name

I am not happy that we're still using string to match the classes.

Still, if used with care strings will work great. Maybe they won't be super fast to match, but it depends on your performance needs. Ideally, we could think about unique ids like ints, hashes or GUIDs.

### Some articles to read and extend

* [ACCU :: Self Registering Classes - Taking polymorphism to the limit](https://accu.org/index.php/journals/597)
* [Self-Registering Objects in C++ | Dr Dobb's](http://www.drdobbs.com/cpp/self-registering-objects-in-c/184410633)
* [c++ - How to force a static member to be initialized? - Stack Overflow](https://stackoverflow.com/questions/6420985/how-to-force-a-static-member-to-be-initialized?noredirect=1&lq=1)
* [Chromium Notes: Static initializers](http://neugierig.org/software/chromium/notes/2011/08/static-initializers.html)
* [Static initializers will murder your family – Monica Dinculescu](https://meowni.ca/posts/static-initializers/)

## Summary

In this post, I've covered a type of factory where types register themselves. It's an opposite way of simple factories where all the types are declared upfront.

Such approach gives more flexibility and removes dependency on the exact list of supported classes from the factory.

The downside is that the classes that want to register need to ask for it and thus they need a bit more code.

Let me know what do you think about self-registration? Do you use it in your projects? Or maybe you have some better ways?

### Call To Action

If you like more programming stories from me, just signup to my weekly newsletter: [Bartek's coding blog newsletter](http://eepurl.com/caCAun)
(You'll also get some C++ bonuses)