GithubHelp home page GithubHelp logo

ybainier / hypodermic Goto Github PK

View Code? Open in Web Editor NEW
559.0 34.0 80.0 695 KB

Hypodermic is an IoC container for C++. It provides dependency injection to your existing design.

License: MIT License

C++ 96.02% C 0.51% CMake 3.47%

hypodermic's Introduction

Hypodermic

MIT license Build status Build Status

Hypodermic is a non-intrusive header only IoC container for C++. It provides dependency injection to your existing design by managing the creation of your components and their dependencies in the right order, sparing you the trouble of writing and maintaining boiler plate code.

Used in production environments since 2012.

First steps

Configure the container by registering your components

ContainerBuilder builder;

builder.registerType< MessageDispatcher >();

auto container = builder.build();

... then ask the container to give you an instance of that type

auto dispatcher = container->resolve< MessageDispatcher >();

Want to discover what happened here? Learn to use more features through the beginner's guide on the wiki.

Benchmarks

Some comparative benchmarks are available on the wiki, check them out.

Acknowledgment

Hypodermic was started with the will to mimic the famous .NET Autofac http://autofac.org/. Although its design evolved, both its behavior and its expressiveness tend to remain the same.

Constructor deduction has been made possible thanks to the work of Krzysztof Jusiak in http://boost-experimental.github.io/di/.

hypodermic's People

Contributors

an9bit avatar borco avatar d-led avatar dimhotepus avatar gurry avatar pck avatar ybainier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hypodermic's Issues

Bug: interface is resolved twice from nested container if they are added as both .as<interface>() and .asSelf()

Hi! Thanks for creating this awesome library, it has saved me so much time and headaches!

I took a fast screenshot from debugger to show my problem:
image

So what is happening here is that I have container and then I'm supposed to reload the plugins at runtime when they are rebuilt (I simplified the code in screenshot to show the issue). Somehow all the systems are resolved twice when I resolve them from application container. I was able to narrow this down in having my systems registered as<core::system>() and .asSelf(). If I remove asSelf() the system is resolved only once from nested container container.

I'm not sure if this is just my setup or wider issue. I´m running
macOS with AppleClang 12.0.5
Boost 1.75 from vcpkg

Type dependencies

Hello there,
Thanks for the very cool project.

Question 1:
I've been using the version you've published in the past, using the INJECT macro in order to declare dependencies of a type.

So for example:

builder.registerType< Car>(CREATE(new Car(INJECT(IDriver))))->as< ICar>()->singleInstance();

in this example, i need to be familiar only with the IDriver interface.

I see that you changed this implementation and now the above should look something like this:

builder.registerType< Car>().with< IDriver, Driver >().as< ICar>().singleInstance();

right?
But now it seems like i need to be familiar with both IDriver and Driver

Am i missing something?

Question 2:
Does the new version compiles faster comparing to the previous release?

Thanks alot,
Amit

Resolve other than shared_ptr (e.g. unique_ptr)

At least for types which are not registered as single instance, i.e. a new instance is returned for every call to resolve(), is there a chance to resolve as something other than shared_ptr, and, specifically, with unique_ptr?
Maybe it's possible to add a method named "resolveUnique" for this? And it would throw if the type cannot be resolved for a unique instance -- whether it's not registered, or registered as single instance.
I am asking this because the use of shared_ptr is often too heavy for what I really need.

[FeatureRequest] Fluent lifetime management

Hi,

As far as I am concerned there are only 3 ways to manage the dependency lifetime. We could either specifically say there should be a single instance:

builder.registerType< MessageDispatcher >()
       .as< IMessageDispatcher >()
       .singleInstance();

or we could use single instance for child container living as long as long child container exist. The last way is default behaviour which I believe is one instance per resolve.

In our application we are concerned about very strong multi-threading. In such scenarios we might want:

  • One instance per thread
  • Multiple instances per thread
  • One instance across multiple threads

So the proposal is to add another syntax like:

builder.registerType< MessageDispatcher >()
       .as< IMessageDispatcher >()
       .withLifetimeManager(InstancePerThreadLifetimeManager());

InstancePerThreadLifetimeManager is an implementation of LifetimeManagerObject exposing the following methods:

  • resolveDependency
  • removeDependency

LifetimeManager has to have access to getOrCreateComponent method so it can make Hypodermic create new instances.

with std::thread::get_id we would be able to implement LifetimeManager so it distributes instances of requested object so there is always exactly one instance per thread. Such implementation injection allows us to fully customize the objects lifetime which is crucial for multi-threading project.

Thanks,
Patryk

Показан перевод для запроса Не компилирует с абстрактными классами и Искать вместо этого перевод для Не компилируеться с абстрактными классами и It does not compile with abstract classes and boos 1.6

I try to create a container for such a simple hierarchy.

include "Hypodermic/ContainerBuilder.h"

include "Hypodermic/Container.h"

class A
{
public:

    virtual void method1()abstract;

};

class B:public A
{
public:
void method1() override
{
}
};

int main()
{
Hypodermic::ContainerBuilder builder;
builder.registerType().asSelf().as().singleInstance();
auto container = builder.build();
container->resolve()->method1();
return 0;
}

Use VS 2015 and boost 1.6. Got error message error C2259: 'A': cannot instantiate abstract class

does not build with clang and <=boost-1.53

It is required to use hypodermic with at least boost-1.54. This should be a boost signals2 bug within boost itself.

I don't think its a major issue, but its nice to know it.

[  3%] Building CXX object Hypodermic/CMakeFiles/Hypodermic.dir/ComponentRegistration.cpp.o
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.cpp:11:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.h:15:
/home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/TypeIndexWorkaround.h:48:5: warning: 'hash' defined as a class template here but previously declared as a struct template [-Wmismatched-tags]
    class hash< type_index > : public std::unary_function< type_index, size_t >
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/bits/functional_hash.h:58:5: note: did you mean class here?
    struct hash;
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/bitset:763:33: note: did you mean class here?
      template<typename> friend struct hash;
                                ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/bits/stl_bvector.h:523:31: note: did you mean class here?
    template<typename> friend struct hash;
                              ^
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.cpp:4:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ActivatedData.h:7:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IActivatedData.h:6:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IComponentContext.h:8:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IComponentRegistration.h:9:
In file included from /usr/include/boost/signals2.hpp:19:
In file included from /usr/include/boost/signals2/signal.hpp:38:
In file included from /usr/include/boost/signals2/variadic_signal.hpp:21:
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:89:16: error: no matching function for call to 'get'
          func(std::get<indices>(args)...);
               ^~~~~~~~~~~~~~~~~
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:78:18: note: in instantiation of function template specialization 'boost::signals2::detail::call_with_tuple_args<boost::signals2::detail::void_type>::m_invoke<boost::function<void (Hypodermic::PreparingData &)>, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
      Hypodermic::PreparingData &, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' requested here
          return m_invoke(resolver, func, indices_type(), args);
                 ^
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:114:18: note: in instantiation of function template specialization 'boost::signals2::detail::call_with_tuple_args<boost::signals2::detail::void_type>::operator()<boost::function<void (Hypodermic::PreparingData &)>, Hypodermic::PreparingData &,
      boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' requested here
          return call_with_tuple_args<result_type>()(connectionBody->slot.slot_function(), _args);
                 ^
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:106:18: note: in instantiation of function template specialization 'boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::PreparingData
      &>::m_invoke<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> > >' requested here
          return m_invoke(connectionBody,
                 ^
/usr/include/boost/signals2/detail/slot_call_iterator.hpp:82:35: note: in instantiation of function template specialization 'boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::PreparingData
      &>::operator()<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> > >' requested here
              cache->result.reset(cache->f(*iter));
                                  ^
/usr/include/boost/iterator/iterator_facade.hpp:514:20: note: in instantiation of member function 'boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::PreparingData &>,
      std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> > >,
      boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> >::dereference' requested here
          return f.dereference();
                   ^
/usr/include/boost/iterator/iterator_facade.hpp:639:40: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
          return iterator_core_access::dereference(this->derived());
                                       ^
/usr/include/boost/signals2/optional_last_value.hpp:55:13: note: in instantiation of member function 'boost::iterator_facade<boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::PreparingData &>,
      std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> > >,
      boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> >, boost::signals2::detail::void_type,
      boost::single_pass_traversal_tag, const boost::signals2::detail::void_type &, long>::operator*' requested here
            *first;
            ^
/usr/include/boost/signals2/detail/result_type_wrapper.hpp:64:11: note: in instantiation of function template specialization 'boost::signals2::optional_last_value<void>::operator()<boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type,
      Hypodermic::PreparingData &>, std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >,
      boost::signals2::mutex> > >, boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> > >' requested here
          combiner(first, last);
          ^
/usr/include/boost/signals2/detail/signal_template.hpp:241:18: note: in instantiation of function template specialization 'boost::signals2::detail::combiner_invoker<void>::operator()<boost::signals2::optional_last_value<void>,
      boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::PreparingData &>, std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int>
      >, boost::signals2::slot<void (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> > >, boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void
      (Hypodermic::PreparingData &), boost::function<void (Hypodermic::PreparingData &)> >, boost::signals2::mutex> > >' requested here
          return detail::combiner_invoker<typename combiner_type::result_type>()
                 ^
/usr/include/boost/signals2/detail/signal_template.hpp:695:16: note: in instantiation of member function 'boost::signals2::detail::signal_impl<void (Hypodermic::PreparingData &), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (Hypodermic::PreparingData &)>,
      boost::function<void (const boost::signals2::connection &, Hypodermic::PreparingData &)>, boost::signals2::mutex>::operator()' requested here
        return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
               ^
/home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.cpp:130:25: note: in instantiation of member function 'boost::signals2::signal<void (Hypodermic::PreparingData &), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (Hypodermic::PreparingData &)>,
      boost::function<void (const boost::signals2::connection &, Hypodermic::PreparingData &)>, boost::signals2::mutex>::operator()' requested here
        preparingSignal_(data);
                        ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:142:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(std::pair<_Tp1, _Tp2>& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:147:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(std::pair<_Tp1, _Tp2>&& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:152:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(const std::pair<_Tp1, _Tp2>& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:268:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(array<_Tp, _Nm>& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:277:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(array<_Tp, _Nm>&& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:285:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(const array<_Tp, _Nm>& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:757:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(tuple<_Elements...>& __t) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:764:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(const tuple<_Elements...>& __t) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:771:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(tuple<_Elements...>&& __t) noexcept
    ^
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.cpp:4:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ActivatedData.h:7:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IActivatedData.h:6:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IComponentContext.h:8:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IComponentRegistration.h:9:
In file included from /usr/include/boost/signals2.hpp:19:
In file included from /usr/include/boost/signals2/signal.hpp:38:
In file included from /usr/include/boost/signals2/variadic_signal.hpp:21:
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:89:16: error: no matching function for call to 'get'
          func(std::get<indices>(args)...);
               ^~~~~~~~~~~~~~~~~
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:78:18: note: in instantiation of function template specialization 'boost::signals2::detail::call_with_tuple_args<boost::signals2::detail::void_type>::m_invoke<boost::function<void (Hypodermic::ActivatingData<void> &)>, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
      Hypodermic::ActivatingData<void> &, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' requested here
          return m_invoke(resolver, func, indices_type(), args);
                 ^
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:114:18: note: in instantiation of function template specialization 'boost::signals2::detail::call_with_tuple_args<boost::signals2::detail::void_type>::operator()<boost::function<void (Hypodermic::ActivatingData<void> &)>, Hypodermic::ActivatingData<void>
      &, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' requested here
          return call_with_tuple_args<result_type>()(connectionBody->slot.slot_function(), _args);
                 ^
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:106:18: note: in instantiation of function template specialization 'boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatingData<void>
      &>::m_invoke<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> > >'
      requested here
          return m_invoke(connectionBody,
                 ^
/usr/include/boost/signals2/detail/slot_call_iterator.hpp:82:35: note: in instantiation of function template specialization 'boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatingData<void>
      &>::operator()<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> > >'
      requested here
              cache->result.reset(cache->f(*iter));
                                  ^
/usr/include/boost/iterator/iterator_facade.hpp:514:20: note: in instantiation of member function 'boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatingData<void> &>,
      std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> > >,
      boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> >::dereference' requested here
          return f.dereference();
                   ^
/usr/include/boost/iterator/iterator_facade.hpp:639:40: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
          return iterator_core_access::dereference(this->derived());
                                       ^
/usr/include/boost/signals2/optional_last_value.hpp:55:13: note: in instantiation of member function 'boost::iterator_facade<boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatingData<void> &>,
      std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> > >,
      boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> >, boost::signals2::detail::void_type,
      boost::single_pass_traversal_tag, const boost::signals2::detail::void_type &, long>::operator*' requested here
            *first;
            ^
/usr/include/boost/signals2/detail/result_type_wrapper.hpp:64:11: note: in instantiation of function template specialization 'boost::signals2::optional_last_value<void>::operator()<boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type,
      Hypodermic::ActivatingData<void> &>, std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void
      (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> > >, boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)>
      >, boost::signals2::mutex> > >' requested here
          combiner(first, last);
          ^
/usr/include/boost/signals2/detail/signal_template.hpp:241:18: note: in instantiation of function template specialization 'boost::signals2::detail::combiner_invoker<void>::operator()<boost::signals2::optional_last_value<void>,
      boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatingData<void> &>, std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group,
      boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> > >, boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >,
      boost::signals2::slot<void (Hypodermic::ActivatingData<void> &), boost::function<void (Hypodermic::ActivatingData<void> &)> >, boost::signals2::mutex> > >' requested here
          return detail::combiner_invoker<typename combiner_type::result_type>()
                 ^
/usr/include/boost/signals2/detail/signal_template.hpp:695:16: note: in instantiation of member function 'boost::signals2::detail::signal_impl<void (Hypodermic::ActivatingData<void> &), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (Hypodermic::ActivatingData<void> &)>,
      boost::function<void (const boost::signals2::connection &, Hypodermic::ActivatingData<void> &)>, boost::signals2::mutex>::operator()' requested here
        return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
               ^
/home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.cpp:141:26: note: in instantiation of member function 'boost::signals2::signal<void (Hypodermic::ActivatingData<void> &), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void
      (Hypodermic::ActivatingData<void> &)>, boost::function<void (const boost::signals2::connection &, Hypodermic::ActivatingData<void> &)>, boost::signals2::mutex>::operator()' requested here
        activatingSignal_(data);
                         ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:142:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(std::pair<_Tp1, _Tp2>& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:147:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(std::pair<_Tp1, _Tp2>&& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:152:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(const std::pair<_Tp1, _Tp2>& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:268:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(array<_Tp, _Nm>& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:277:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(array<_Tp, _Nm>&& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:285:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(const array<_Tp, _Nm>& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:757:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(tuple<_Elements...>& __t) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:764:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(const tuple<_Elements...>& __t) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:771:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(tuple<_Elements...>&& __t) noexcept
    ^
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.cpp:4:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/ActivatedData.h:7:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IActivatedData.h:6:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IComponentContext.h:8:
In file included from /home/karol/Dokumente/repos/hypodermic/Hypodermic/../Hypodermic/IComponentRegistration.h:9:
In file included from /usr/include/boost/signals2.hpp:19:
In file included from /usr/include/boost/signals2/signal.hpp:38:
In file included from /usr/include/boost/signals2/variadic_signal.hpp:21:
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:89:16: error: no matching function for call to 'get'
          func(std::get<indices>(args)...);
               ^~~~~~~~~~~~~~~~~
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:78:18: note: in instantiation of function template specialization 'boost::signals2::detail::call_with_tuple_args<boost::signals2::detail::void_type>::m_invoke<boost::function<void (Hypodermic::ActivatedData<void> &)>, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
      Hypodermic::ActivatedData<void> &, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' requested here
          return m_invoke(resolver, func, indices_type(), args);
                 ^
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:114:18: note: in instantiation of function template specialization 'boost::signals2::detail::call_with_tuple_args<boost::signals2::detail::void_type>::operator()<boost::function<void (Hypodermic::ActivatedData<void> &)>, Hypodermic::ActivatedData<void> &,
      boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' requested here
          return call_with_tuple_args<result_type>()(connectionBody->slot.slot_function(), _args);
                 ^
/usr/include/boost/signals2/detail/variadic_slot_invoker.hpp:106:18: note: in instantiation of function template specialization 'boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatedData<void>
      &>::m_invoke<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> > >'
      requested here
          return m_invoke(connectionBody,
                 ^
/usr/include/boost/signals2/detail/slot_call_iterator.hpp:82:35: note: in instantiation of function template specialization 'boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatedData<void>
      &>::operator()<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> > >'
      requested here
              cache->result.reset(cache->f(*iter));
                                  ^
/usr/include/boost/iterator/iterator_facade.hpp:514:20: note: in instantiation of member function 'boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatedData<void> &>,
      std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> > >,
      boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> >::dereference' requested here
          return f.dereference();
                   ^
/usr/include/boost/iterator/iterator_facade.hpp:639:40: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
          return iterator_core_access::dereference(this->derived());
                                       ^
/usr/include/boost/signals2/optional_last_value.hpp:55:13: note: in instantiation of member function 'boost::iterator_facade<boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatedData<void> &>,
      std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> > >,
      boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> >, boost::signals2::detail::void_type,
      boost::single_pass_traversal_tag, const boost::signals2::detail::void_type &, long>::operator*' requested here
            *first;
            ^
/usr/include/boost/signals2/detail/result_type_wrapper.hpp:64:11: note: in instantiation of function template specialization 'boost::signals2::optional_last_value<void>::operator()<boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type,
      Hypodermic::ActivatedData<void> &>, std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void
      (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> > >, boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >,
      boost::signals2::mutex> > >' requested here
          combiner(first, last);
          ^
/usr/include/boost/signals2/detail/signal_template.hpp:241:18: note: in instantiation of function template specialization 'boost::signals2::detail::combiner_invoker<void>::operator()<boost::signals2::optional_last_value<void>,
      boost::signals2::detail::slot_call_iterator_t<boost::signals2::detail::variadic_slot_invoker<boost::signals2::detail::void_type, Hypodermic::ActivatedData<void> &>, std::_List_iterator<boost::shared_ptr<boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group,
      boost::optional<int> >, boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> > >, boost::signals2::detail::connection_body<std::pair<boost::signals2::detail::slot_meta_group, boost::optional<int> >,
      boost::signals2::slot<void (Hypodermic::ActivatedData<void> &), boost::function<void (Hypodermic::ActivatedData<void> &)> >, boost::signals2::mutex> > >' requested here
          return detail::combiner_invoker<typename combiner_type::result_type>()
                 ^
/usr/include/boost/signals2/detail/signal_template.hpp:695:16: note: in instantiation of member function 'boost::signals2::detail::signal_impl<void (Hypodermic::ActivatedData<void> &), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (Hypodermic::ActivatedData<void> &)>,
      boost::function<void (const boost::signals2::connection &, Hypodermic::ActivatedData<void> &)>, boost::signals2::mutex>::operator()' requested here
        return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
               ^
/home/karol/Dokumente/repos/hypodermic/Hypodermic/ComponentRegistration.cpp:153:25: note: in instantiation of member function 'boost::signals2::signal<void (Hypodermic::ActivatedData<void> &), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (Hypodermic::ActivatedData<void> &)>,
      boost::function<void (const boost::signals2::connection &, Hypodermic::ActivatedData<void> &)>, boost::signals2::mutex>::operator()' requested here
        activatedSignal_(data);
                        ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:142:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(std::pair<_Tp1, _Tp2>& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:147:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(std::pair<_Tp1, _Tp2>&& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/utility:152:5: note: candidate template ignored: could not match 'pair' against 'tuple'
    get(const std::pair<_Tp1, _Tp2>& __in) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:268:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(array<_Tp, _Nm>& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:277:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(array<_Tp, _Nm>&& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/array:285:5: note: candidate template ignored: could not match 'array' against 'tuple'
    get(const array<_Tp, _Nm>& __arr) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:757:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(tuple<_Elements...>& __t) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:764:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(const tuple<_Elements...>& __t) noexcept
    ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/tuple:771:5: note: candidate template ignored: could not match 'std::tuple' against 'boost::tuples::tuple'
    get(tuple<_Elements...>&& __t) noexcept
    ^
1 warning and 3 errors generated.
Hypodermic/CMakeFiles/Hypodermic.dir/build.make:80: recipe for target 'Hypodermic/CMakeFiles/Hypodermic.dir/ComponentRegistration.cpp.o' failed
make[2]: *** [Hypodermic/CMakeFiles/Hypodermic.dir/ComponentRegistration.cpp.o] Error 1
CMakeFiles/Makefile2:140: recipe for target 'Hypodermic/CMakeFiles/Hypodermic.dir/all' failed
make[1]: *** [Hypodermic/CMakeFiles/Hypodermic.dir/all] Error 2
Makefile:146: recipe for target 'all' failed
make: *** [all] Error 2

Question: register two interfaces for same concrete class

Suppose Foo implements ISome and IThing. How does one register both interfaces, while ensuring that there is only a single Foo instance?

I can achieve it by using a factory method for one of the interfaces, and some dynamic_cast wizardry. Would be nice if Hypodermic allowed chaining as<...>() to register multiple interfaces.

pkg-config: 'libdir' not defined

Hello.

The generated pkgconfig/libhypodermic.pc doesn't work because libdir is not set.
I'm not sure, but maybe the "Libs: .. -lboost_system" line isn't even necessary and can be deleted.

$ pkg-config --cflags libhypodermic
Variable 'libdir' not defined in '/usr/local/lib/pkgconfig/libhypodermic.pc'

Kind regards, Paul

Is there a version without boost

I really like the DI style of C# autofac, and it would be great if they could be used in C++.

But I hope there's no need to introduce overly large libraries (such as boost)

Is it possible to specify the dependency explicitly while resolving

Hi

I have the following classes:

class IDatabaseConnection;

class RepositoryA : public IRepositoryA {
  RepositoryA(std::shared_ptr<IDatabaseConnection>);
};

class RepositoryB : public IRepositoryB {
  RepositoryB(std::shared_ptr<IDatabaseConnection>);
};

In some cases, I want the same IDatabaseConnection to be shared when constructing RepositoryA and RepositoryB:

auto db = container->resolve<IDatabaseConnection>();
db->startTransaction();

auto repoA = container->resolve<IRepositoryA>(); // here I want to pass db explicitly to the constructor
auto repoB = container->resolve<IRepositoryB>(); // here I want to use db explicitly to the constructor

db->commit();

Note that in other cases, sharing the db instance is not necessary or desired (which is the default behaviour of Hypodermic)

Is it possible to achieve this behaviour? and if so, could you please provide an example?

Thanks

ContainerBuilder doesn't have a virtual destructor

Hello,
In this section of the beginner guide, it's suggesting to inherit from the ContainerBuilder class.

However we have noticed that ContainerBuilder class doesn't have a virtual destructor.
Is that a bug? Inheriting from that class may cause undefined behaviour

@ybainier - can you please clarify that? Thanks.

No release/tags

There is no tags in this repository which makes hard to know what is considered stable or not.
@ybainier, can you include some tags/releases?

Compile errors: multiple definition of boost::*

Hello. I tried to build your project on Linux (ArchLinux, x86_64) and got errors on linking.

fatal: No annotated tags can describe '3e86a5a1fd5e8279d6ca461f9f398fa3f3c2eddc'.
However, there were unannotated tags: try --tags.
[popov@archlinux Hypodermic]$ cmake -S ./ -B build 
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Checking for g++ version >= 4.8
-- Performing Test FLAG_CXX11
-- Performing Test FLAG_CXX11 - Success
-- C++11 features enabled
-- Found Boost: /usr/lib64/cmake/Boost-1.71.0/BoostConfig.cmake (found version "1.71.0") found components:  system unit_test_framework 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/popov/Projects/C++/Tests/Hypodermic/build
[popov@archlinux Hypodermic]$ cd build
[popov@archlinux build]$ make -j 12 > /dev/null 2> ~/log

Like this:

/usr/bin/ld: CMakeFiles/Hypodermic.Tests.dir/ContainerBuilderTests.cpp.o: in function `boost::unit_test::output::compiler_log_formatter::log_entry_value(std::ostream&, boost::unit_test::lazy_ostream const&)':
ContainerBuilderTests.cpp:(.text+0x0): multiple definition of `boost::unit_test::output::compiler_log_formatter::log_entry_value(std::ostream&, boost::unit_test::lazy_ostream const&)'; CMakeFiles/Hypodermic.Tests.dir/CircularDependencyTests.cpp.o:CircularDependencyTests.cpp:(.text+0x0): first defined here

Full dump of errors: log.txt

Versions:

  • Boost 1.71.0-4
  • gcc 9.2.0-4
  • cmake 3.15.5-1

Issue when resolving same types in different shared libraries

Hi!

I've had long running issue in my project in which, when I try to resolve a type in functions from different shared libraries (dylib, I'm running macOS) I have had different results. Steps to repro are:

  • I have executable, library that is dynamically linked and then one that I hot reload
  • In my linked library I have builder which creates a container.
  • In my hot-reloadable library I have builder which I use to register types for nested container
  • After new types have been created I'm resolving some systems

Issue is that If in my hot-reloadable library try to resolve from my container I get completely new instance for all singletons. It is as if comparing of types is not working -- and it isn't. I was looking and TypeAlias, TypeKeyKey and TypeInfo and they use std::type_info. After fast googling it would seem that operating with type_info and type_index are undefined behaviour between different DLLs, so they are not comparable. As it is UB this might not be an issue in all OSs or compilers. I have tested this with this changeset and it fixes my issue as the name of the class is of course same in my whole application. I'm not sure yet of side-effects this might have, but it works great for me.

I then asked ChatGPT if it knows the answer to this and it provided me with following answer (I have no idea if this is correct or not, its ChatGPT):

It is generally not safe to compare typeid of a class in different shared libraries. 
The typeid operator returns a type_info object that provides information about the type of an object. 
This information is implementation-defined, and may be different between different compilers, libraries, or even different versions of the same library.
If you need to compare the types of objects from different shared libraries, you should provide a unique identifier for each type that is guaranteed to be consistent across all libraries. 
This can be achieved by using a unique identifier for each type, such as a string or an integer, and comparing the identifier instead of the typeid.
In C++17 and later, you can use the std::type_index class to compare types across shared libraries. 
The std::type_index class stores a type_info object and provides a hash function that allows you to compare types in a consistent manner across different libraries.

So maybe storing type_index in TypeInfo is the real answer? I'm really not sure. I know my use-case might be a bit niche but it would be great if something similar would be implemented upstream.

EDIT: I did try just storing type_index but it had the original effech: not working

Autowiring of factory methods

In order to achieve full dependency inversion, I don't want to expose the concrete classes from code modules, but rather factory methods creating concrete objects implementing a given interface. They look like this:

struct IFoo { ... };
struct IBar { ... };

struct FooFactory
{
    static std::unique_ptr<IFoo> createInstance(std::shared_ptr<IBar>);
    FooFactory() = delete;
};

Unfortunately, registering the factory is very verbose:

builder.registerInstanceFactory([=](Hypodermic::ComponentContext& context) 
    -> std::shared_ptr<IFoo> {
        return FooFactory::createInstance(context.resolve<IBar>());
        });

(1) Would it be possible to provide auto-wiring for factory methods, just as for constructors, something likes this:

builder.registerInstanceFactory(FooFactory::createInstance).as<IFoo>();

NOTE: the factories return std::unique_ptr not std::shared_ptr because they are IoC (Hypodermic) agnostic. Converting from the former to the later is trivial. But still, Hypodermic currently requires one to force that conversion (-> std::shared_ptr<IFoo>). Would be nice if that was implicit.

How to inject a factory for named instances?

https://github.com/ybainier/Hypodermic/wiki/Expressing-dependencies#injecting-an-instance-factory gives an example of injecting a function that can be used as a factory. However, this seems to only work with anonymously-registered types. It seems there's no way to get a factory function that I could pass a name to, to get a named implementation back, is that right? I tried requesting a function that takes a const &string, but that didn't compile. How hard would it be to add that feature?

License not listed

The google code page used to list an MIT license. I'm interested in using this code. Could you add a license to this repo?

Alternatives to `std::make_shared`

Would it be possible to add the ability to create instances with something other than std::make_shared. Some of our objects require a custom deleter and it seems that we cannot inject the deleter when registering types.

Is there a way to accomplish this now by inheriting from a container builder?

Checking for not null.

Hi!

I would like to get an error either at compile time or at runtime if a specific type is required, but was not registered. Is it possible?

Не работает с Visual Studio 2015 (v140) и boost

`

include "Hypodermic/ContainerBuilder.h"

include "Hypodermic/Container.h"

class A
{
public:
virtual void method1()=0;
};
class B:public A
{
public:
void method1() override
{
}
};
int main()
{
Hypodermic::ContainerBuilder builder;
builder.registerType< B >().as< A >();
auto container = builder.build();
container->resolve< A >()->method1();
return 0;
}
`
Output :
1>------ Build started: Project: hypodermic, Configuration: Debug Win32 ------
1> hypodermic.cpp
1>c:\external_libs\boost_1_60_0\boost\utility\value_init.hpp(72): error C2259: 'A': cannot instantiate abstract class
1> c:\external_libs\boost_1_60_0\boost\utility\value_init.hpp(72): note: due to following members:
1> c:\external_libs\boost_1_60_0\boost\utility\value_init.hpp(72): note: 'void A::method1(void)': is abstract
1> c:\projects\test\hypodermic\hypodermic\hypodermic.cpp(12): note: see declaration of 'A::method1'
1> c:\external_libs\boost_1_60_0\boost\utility\value_init.hpp(93): note: see reference to class template instantiation 'boost::initialized::wrapper' being compiled
1> with
1> [
1> T=arg
1> ]
1> c:\external_libs\boost_1_60_0\boost\utility\value_init.hpp(198): note: see reference to class template instantiation 'boost::initialized' being compiled
1> with
1> [
1> T=arg
1> ]
1> c:\external_libs\boost_1_60_0\boost\mpl\for_each.hpp(77): note: see reference to class template instantiation 'boost::value_initialized' being compiled
1> c:\external_libs\boost_1_60_0\boost\mpl\for_each.hpp(105): note: see reference to function template instantiation 'void boost::mpl::aux::for_each_impl::execute<first,last,TransformOp,F>(Iterator ,LastIterator *,TransformFunc *,F)' being compiled
1> with
1> [
1> TransformOp=boost::mpl::identityboost::mpl::na,
1> F=Hypodermic::Details::RegisteredBaseToString,
1> Iterator=first,
1> LastIterator=last,
1> TransformFunc=boost::mpl::identityboost::mpl::na
1> ]
1> c:\external_libs\boost_1_60_0\boost\mpl\for_each.hpp(118): note: see reference to function template instantiation 'void boost::mpl::for_each<Sequence,boost::mpl::identityboost::mpl::na,F>(F,Sequence *,TransformOp *)' being compiled
1> with
1> [
1> Sequence=RegisteredBases,
1> F=Hypodermic::Details::RegisteredBaseToString,
1> TransformOp=boost::mpl::identityboost::mpl::na
1> ]
1> c:\external_libs\hypodermic\hypodermic\registrationdescriptorinfotostring.h(133): note: see reference to function template instantiation 'void boost::mpl::for_each<RegisteredBases,Hypodermic::Details::RegisteredBaseToString>(F,Sequence *)' being compiled
1> with
1> [
1> F=Hypodermic::Details::RegisteredBaseToString,
1> Sequence=RegisteredBases
1> ]
1> c:\external_libs\hypodermic\hypodermic\registrationdescriptorinfo.h(136): note: see reference to function template instantiation 'std::string Hypodermic::RegistrationDescriptorInfoToString::toStringHypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<T,boost::mpl::set0boost::mpl::na::item_,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>>(void)' being compiled
1> with
1> [
1> T=A
1> ]
1> c:\external_libs\hypodermic\hypodermic\registrationdescriptorinfo.h(135): note: while compiling class template member function 'std::string Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<T,boost::mpl::set0boost::mpl::na::item
>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>::toString(void)'
1> with
1> [
1> T=A
1> ]
1> c:\external_libs\hypodermic\hypodermic\defaultconstructibleregistrationdescriptor.h(71): note: see reference to function template instantiation 'std::string Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<T,boost::mpl::set0boost::mpl::na::item_>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>::toString(void)' being compiled
1> with
1> [
1> T=A
1> ]
1> c:\external_libs\hypodermic\hypodermic\as.h(22): note: see reference to class template instantiation 'Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<T,boost::mpl::set0boost::mpl::na::item_>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>' being compiled
1> with
1> [
1> T=A
1> ]
1> c:\external_libs\hypodermic\hypodermic\defaultconstructibleregistrationdescriptor.h(19): note: see reference to class template instantiation 'Hypodermic::RegistrationDescriptorOperations::AsHypodermic::DefaultConstructibleRegistrationDescriptor<TNewDescriptorInfo,TDescriptorInfo>' being compiled
1> with
1> [
1> TNewDescriptorInfo=Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<A,boost::mpl::set0boost::mpl::na::item_>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>,
1> TDescriptorInfo=Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<A,boost::mpl::set0boost::mpl::na::item_>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(391): note: see reference to class template instantiation 'Hypodermic::DefaultConstructibleRegistrationDescriptor' being compiled
1> with
1> [
1> TNewDescriptorInfo=Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<A,boost::mpl::set0boost::mpl::na::item_>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(526): note: see reference to class template instantiation 'std::is_convertible<Ty2 *,Ty *>' being compiled
1> with
1> [
1> Ty2=Hypodermic::DefaultConstructibleRegistrationDescriptorHypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<A,boost::mpl::set0boost::mpl::na::item_,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>>,
1> Ty=Hypodermic::IRegistrationDescriptor
1> ]
1> c:\projects\test\hypodermic\hypodermic\hypodermic.cpp(26): note: see reference to function template instantiation 'Hypodermic::DefaultConstructibleRegistrationDescriptor &Hypodermic::RegistrationDescriptorOperations::AsHypodermic::DefaultConstructibleRegistrationDescriptor<Hypodermic::RegistrationDescriptorInfo<T,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::setboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>,TDescriptorInfo>::as<A,TDescriptor>(void)' being compiled
1> with
1> [
1> TNewDescriptorInfo=Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<A,boost::mpl::set0boost::mpl::na::item
>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>,
1> T=B,
1> TDescriptorInfo=Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::setboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>,
1> TDescriptor=Hypodermic::DefaultConstructibleRegistrationDescriptorHypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::setboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>
1> ]
1> c:\projects\test\hypodermic\hypodermic\hypodermic.cpp(26): note: see reference to function template instantiation 'Hypodermic::DefaultConstructibleRegistrationDescriptor &Hypodermic::RegistrationDescriptorOperations::AsHypodermic::DefaultConstructibleRegistrationDescriptor<Hypodermic::RegistrationDescriptorInfo<T,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::setboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>,TDescriptorInfo>::as<A,TDescriptor>(void)' being compiled
1> with
1> [
1> TNewDescriptorInfo=Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::s_item<A,boost::mpl::set0boost::mpl::na::item
>,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>,
1> T=B,
1> TDescriptorInfo=Hypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::setboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>,
1> TDescriptor=Hypodermic::DefaultConstructibleRegistrationDescriptorHypodermic::RegistrationDescriptorInfo<B,Hypodermic::InstanceLifetimes::Transient,Hypodermic::Tags::NotSelfRegistered,boost::mpl::setboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::mapboost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>
1> ]
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory(349): error C4996: 'std::Uninitialized_copy0': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory(336): note: see declaration of 'std::Uninitialized_copy0'
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(191): note: see reference to function template instantiation 'FwdIt std::uninitialized_copy<I,boost::variant<boost::shared_ptr,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_>>(InIt,InIt,FwdIt)' being compiled
1> with
1> [
1> FwdIt=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> ,
1> I=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *,
1> InIt=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(178): note: see reference to function template instantiation 'void boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<Ty>>::copy_rai<I,false>(I,I,boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *,const boost::integral_constant<bool,false> &)' being compiled
1> with
1> [
1> Ty=boost::signals2::detail::void_shared_ptr_variant,
1> I=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(178): note: see reference to function template instantiation 'void boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<Ty>>::copy_rai<I,false>(I,I,boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *,const boost::integral_constant<bool,false> &)' being compiled
1> with
1> [
1> Ty=boost::signals2::detail::void_shared_ptr_variant,
1> I=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(204): note: see reference to function template instantiation 'void boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<Ty>>::copy_impl(I,I,boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *,std::random_access_iterator_tag)' being compiled
1> with
1> [
1> Ty=boost::signals2::detail::void_shared_ptr_variant,
1> I=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(203): note: see reference to function template instantiation 'void boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<Ty>>::copy_impl(I,I,boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *,std::random_access_iterator_tag)' being compiled
1> with
1> [
1> Ty=boost::signals2::detail::void_shared_ptr_variant,
1> I=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(288): note: see reference to function template instantiation 'void boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<Ty>>::copy_implboost::variant<boost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_>>(I,I,boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> )' being compiled
1> with
1> [
1> Ty=boost::signals2::detail::void_shared_ptr_variant,
1> I=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(288): note: see reference to function template instantiation 'void boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<Ty>>::copy_implboost::variant<boost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_>>(I,I,boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *)' being compiled
1> with
1> [
1> Ty=boost::signals2::detail::void_shared_ptr_variant,
1> I=boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(281): note: while compiling class template member function 'boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<Ty>>::move_to_new_buffer(unsigned int,const boost::false_type &)'
1> with
1> [
1> Ty=boost::signals2::detail::void_shared_ptr_variant
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\auto_buffer.hpp(302): note: see reference to function template instantiation 'boost::variantboost::shared_ptr<void,boost::signals2::detail::foreign_void_shared_ptr,boost::detail::variant::void
,boost::detail::variant::void
,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_> *boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<_Ty>>::move_to_new_buffer(unsigned int,const boost::false_type &)' being compiled
1> with
1> [
1> _Ty=boost::signals2::detail::void_shared_ptr_variant
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\slot_call_iterator.hpp(64): note: see reference to class template instantiation 'boost::signals2::detail::auto_bufferboost::signals2::detail::void_shared_ptr_variant,boost::signals2::detail::store_n_objects<10,boost::signals2::detail::default_grow_policy,std::allocator<_Ty>>' being compiled
1> with
1> [
1> _Ty=boost::signals2::detail::void_shared_ptr_variant
1> ]
1> c:\external_libs\boost_1_60_0\boost\signals2\detail\slot_call_iterator.hpp(69): note: see reference to class template instantiation 'boost::signals2::detail::slot_call_iterator_cache<ResultType,Function>' being compiled
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

GUN C++ 4.7.3 Compiler error

Hi ybainier,

I encounter the compiler error as below message:

BuildFiles/GNU_ARM_DEBUG/makefile.mk:394: Main.o' failed
In file included from usr/include/Hypodermic/ComponentContext.h:12:0,
from usr/include/Hypodermic/Container.h:6,
from usr/include/Hypodermic/ContainerBuilder.h:8,
from usr/include/Hypodermic/Hypodermic.h:3,
from Src/Main.cpp:13:
usr/include/Hypodermic/IRegistrationScope.h:19:17: error: looser throw specifier for 'virtual Hypodermic::IRegistrationScope::~IRegistrationScope()'
In file included from usr/include/Hypodermic/IRegistrationScope.h:5:0,
from usr/include/Hypodermic/ComponentContext.h:12,
from usr/include/Hypodermic/Container.h:6,
from usr/include/Hypodermic/ContainerBuilder.h:8,
from usr/include/Hypodermic/Hypodermic.h:3,
from Src/Main.cpp:13:
usr/include/Hypodermic/IRegistrationRegistry.h:15:17: error: overriding 'virtual Hypodermic::IRegistrationRegistry::~IRegistrationRegistry() noexcept (true)'
In file included from usr/include/Hypodermic/Registration.h:10:0,
from usr/include/Hypodermic/RegistrationBuilder.h:10,
from usr/include/Hypodermic/AutowireableConstructorRegistrationDescriptor.h:10,
from usr/include/Hypodermic/RegistrationDescriptorBuilder.h:6,
from usr/include/Hypodermic/ContainerBuilder.h:12,
from usr/include/Hypodermic/Hypodermic.h:3,
from Src/Main.cpp:13:
usr/include/Hypodermic/RegistrationActivator.h:20:11: error: looser throw specifier for 'virtual Hypodermic::RegistrationActivator::~RegistrationActivator()'
In file included from usr/include/Hypodermic/ResolutionContainer.h:16:0,
from usr/include/Hypodermic/RegistrationScope.h:11,
from usr/include/Hypodermic/NestedRegistrationScope.h:8,
from usr/include/Hypodermic/ComponentContext.h:16,
from usr/include/Hypodermic/Container.h:6,
from usr/include/Hypodermic/ContainerBuilder.h:8,
from usr/include/Hypodermic/Hypodermic.h:3,
from Src/Main.cpp:13:
usr/include/Hypodermic/IRegistrationActivator.h:16:17: error: overriding 'virtual Hypodermic::IRegistrationActivator::~IRegistrationActivator() noexcept (true)'
In file included from usr/include/Hypodermic/RegistrationBuilder.h:10:0,
from usr/include/Hypodermic/AutowireableConstructorRegistrationDescriptor.h:10,
from usr/include/Hypodermic/RegistrationDescriptorBuilder.h:6,
from usr/include/Hypodermic/ContainerBuilder.h:12,
from usr/include/Hypodermic/Hypodermic.h:3,
from Src/Main.cpp:13:
usr/include/Hypodermic/Registration.h:20:11: error: looser throw specifier for 'virtual Hypodermic::Registration::~Registration()'
In file included from usr/include/Hypodermic/ComponentContext.h:11:0,
from usr/include/Hypodermic/Container.h:6,
from usr/include/Hypodermic/ContainerBuilder.h:8,
from usr/include/Hypodermic/Hypodermic.h:3,
from Src/Main.cpp:13:
usr/include/Hypodermic/IRegistration.h:19:17: error: overriding 'virtual Hypodermic::IRegistration::~IRegistration() noexcept (true)'
make: *** [Obj/GNU_ARM_DEBUG/Main.o] Error 1
make: Target 'build' not remade because of errors.

My main content :

#include <Hypodermic/Hypodermic.h>

int main()
{
rerurn 0;
}

I only want to build successfully.

Whether this c++ version doesn't support c++ 4.7.3 ?

Please help.

Thank you very much.

Neil

static assertion failed: TArg should be a complete type

Hello. I got this compile error, when I try to use forward declaration of dependencies of my classes:

Hypodermic/ArgumentResolver.h:30: static assertion failed: TArg should be a complete type
IPBPolymasterMassStorage/EquipmentWizardPage.cpp:69: required from here

EquipmentWizardPage.h:

#ifndef EQUIPMENTWIZARDPAGE_H
#define EQUIPMENTWIZARDPAGE_H

class DataManager;
namespace Hypodermic {
class Container;
}

#include <DeviceGate/DeviceGateDeviceInformationMessage.h>
#include <Escar/DataTypes/EscarDataTypes.h>
#include <QWizardPage>
#include <memory>

namespace Ui {
class EquipmentWizardPage;
}

class EquipmentWizardPage : public QWizardPage {

    Q_OBJECT

public:
    explicit EquipmentWizardPage(
        std::shared_ptr<DataManager> dataManager,
        std::shared_ptr<Hypodermic::Container> container,
        QWidget* parent = nullptr);
    virtual ~EquipmentWizardPage() override;
...
};

EquipmentWizardPage.cpp:

#include "EquipmentWizardPage.h"
#include "DataContainers/GeneralDataContainer.h"
#include "Dialogs/EquipmentGetDialog.h"
#include "Managers/DataManager.h"
#include "ui_EquipmentWizardPage.h"
#include <Hypodermic/Container.h>

void EquipmentWizardPage::on_pbEquipmentChange_clicked()
{
69: auto equipmentGetDialog = m_container->resolve<EquipmentGetDialog>();
    equipmentGetDialog->setParent(this);
    equipmentGetDialog->setFilterByUnits(true);
    equipmentGetDialog->setUnitsReadOnly(true);
    equipmentGetDialog->setCheckedUnits(m_units);
    equipmentGetDialog->setSerialRequired(true);
    if (equipmentGetDialog->exec() == QDialog::Accepted) {
        m_equipment = equipmentGetDialog->selectedEquipment();
        m_equipmentSerial = equipmentGetDialog->selectedEquipmentSerial();
        updateUi();
    }
}

EquipmentGetDialog.h:

#ifndef EQUIPMENTGETDIALOG_H
#define EQUIPMENTGETDIALOG_H

class DataManager;

#include "Models/CustomStringListModel.h"

#include <Escar/DataTypes/EscarDataTypes.h>
#include <QDialog>
#include <memory>

namespace Ui {
class EquipmentGetDialog;
}

class EquipmentGetDialog : public QDialog {

    Q_OBJECT

public:
    explicit EquipmentGetDialog(
        std::shared_ptr<DataManager> dataManager,
        QWidget* parent = nullptr);
    ~EquipmentGetDialog();
...
};

When I use include of headers of dependencies classes everywhere instead of forward declaration it works fine on linux. I got allocation memory error on windows in this case.

Resolution by name using TBase as T itself

The named binder requires that a TBase parameter is passed to it. However, this makes impossible to create a named reference to objects without a base class, due to its EnforceBaseOf implementation.

struct MyClass {};
Hypodermic::ContainerBuilder builder;
builder.registerType<MyClass>.named<MyClass>(); // fails with TBase should be a base of T

By changing EnforceBaseOf static_assert to

static_assert(std::is_base_of< TBase, T >::value, "TBase should be T itself or a base of T");

the code compiles and run fine, but this does not seem like a clean solution to this problem.

Is there any specific reason why you have explicitly excluded non-polymorphic classes from the named resolution? If you think this solution is good enough, I can provide a pull request with the given changes and some test cases.

Resolution of single instances based on concrete and abstract types

Greetings, I'm using this container and am really quite happy with it. However, there is one quirk that I've found myself working around and I wonder if it's something that you would consider changing or if it's even possible.

I have some code that does the following:

Hypodermic::ContainerBuilder builder;

builder.registerType<ConcreteClass>().as<InterfaceClass>().singleInstance();
...
auto container = builder.build();
...
auto singleton_interface_ref = container->resolve<InterfaceClass>();
auto singleton_concrete_ref = container->resolve<ConcreteClass>();

assert(singleton_interface_ref == singleton_concrete_ref); // Fails!

auto singleton_concrete_ref2 = container->resolve<ConcreteClass>();
assert(singleton_concrete_ref == singleton_concrete_ref2); // Passes

auto singleton_interface_ref2 = container->resolve<InterfaceClass>();
assert(singleton_interface_ref == singleton_interface_ref2); // Passes

Is it possible to have Hypodermic resolve the same reference regardless of whether you resolve the type ConcreteClass or InterfaceClass? My actual use-case is more layered than this, but I thought I'd start out with an illustrative example to see if it was even possible.

Thanks!

Resolve a chain of instantiate of explicit dependencies name?

Hi,

Whether or not Hypodermic will dynamically resolve a specific instantiates with explicit dependency name?

For example :

class IMessageSerializer{...};
class class LengthPrefixedMessageSerializer_1 : public IMessageSerializer {...};
class class LengthPrefixedMessageSerializer_2 : public IMessageSerializer {...};
class class LengthPrefixedMessageSerializer_3 : public IMessageSerializer {...};

class IMessageWriter{};

class ConsoleMessageWriter : public IMessageWriter
{
public:
explicit ConsoleMessageWriter(std::shared_ptr< IMessageSerializer > serializer)
: m_serializer(serializer)
{
}
...
};

builder.registerType< LengthPrefixedMessageSerializer_1 >().as< IMessageSerializer >().named("N1");

builder.registerType< LengthPrefixedMessageSerializer_2 >().as< IMessageSerializer >().named("N2");

builder.registerType< LengthPrefixedMessageSerializer_3 >().as< IMessageSerializer >().named("N3");;

builder.registerType< ConsoleMessageWriter >().as< IMessageWriter >();

std::shared_ptr< Hypodermic::Container > m_container;

m_container = builder.build();

auto messageWriter = m_container->resolve< IMessageWriter >();

While I resolve the IMessageWriter, base on tutor page "Fallback registrations" it will always return a type by using its last registration. There IMessageWriter was resolved an instance with LengthPrefixedMessageSerializer_3.

How to dynamically assign a specific instance with an explicit dependency name to IMessageWriter with LengthPrefixedMessageSerializer_1 ~ 3 ?

Thank you.

Neil

============================================
I read all tutor page, I found a "with" method help me bondle LengthPrefixedMessageSerializer_1 ~ 3 like this example :

builder.registerType< ConsoleMessageWriter >().
with<IMessageSerializer , LengthPrefixedMessageSerializer_1 >()
.as< IMessageWriter >();

So, I resolved IMessageWriter which is returned ConsoleMessageWriter with LengthPrefixedMessageSerializer_1.

But..., It's not good for me. If I need LengthPrefixedMessageSerializer_1 ~ 3, I will create IMessageWriter_1 ~ 3 for mapping...

So, whether or not has a method will help me decode those name interface dynamically.

Thank you very much.

Neil

Hi,

I trace the stackoverflow for this situation, I should change the injection method to "Method Injection".
So, rewrite code as below :

builder.registerType< LengthPrefixedMessageSerializer_1 >().named< IMessageSerializer >("N1");

builder.registerType< LengthPrefixedMessageSerializer_2 >().named< IMessageSerializer >("N2");

builder.registerType< LengthPrefixedMessageSerializer_3 >().named< IMessageSerializer >("N3");

ConsoleMessageWriter : public IMessageWriter
{
public:
explicit ConsoleMessageWriter()
{
}
void SetMessageSerializer (std::shared_ptr< IMessageSerializer > serializer)
{
m_serializer = serializer;
}

...

};

And then,

auto messageWriter = m_container->resolve<IMessageWriter>();	
auto serializer = m_container->resolveNamed<IMessageSerializer>("N2");

	messageWriter->SetMessageSerializer (serializer);

I think it is a good idea for this situation.

Neil

Using .with<T>(instance)

I'm trying to set up a call to .with() when registering a type with an existing instance of an object, following the sample on the Hypodermic github site, as shown below. The .with() executes without incident, but it does not wire up the dependency in the parent object, which is left empty. According to the docs, it seems this should work. Is there something I'm doing wrong?

class IFoo
{
public:
virtual void Bar() = 0;
};

class Foo : public IFoo
{
public:
virtual void Bar() override {};
};

class IBaz { };

class Baz : public IBaz
{
public:
Baz(std::shared_ptr foo) : m_pFoo(foo) {};
std::shared_ptr m_pFoo;
};

Hypodermic::ContainerBuilder builder;
auto foo = std::make_shared();
builder.registerType() .with(foo) .as();
builder.build();

auto pBaz = pContainer->resolve();

Visual Studio 2017 does not build lib

I have clone the repository. open solution right click on the Hypodermic project and select build option.

1>------ Rebuild All started: Project: Hypodermic, Configuration: Debug x64 ------
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

that is all what I got and there is no Hypodermic.lib in output folder.

Please help.

Bug: singleInstance not working as expected when resolving from nested containers

I have a problem when resolving service that is meant to be used as singleInstance from nested containers. I have written a test case here:

#include <cassert>

#include <Hypodermic/ContainerBuilder.h>

struct interface
{
    virtual bool& get_value() = 0;
};

struct service : interface
{
    bool& get_value() final { return value; }

    bool value{};
};

int main(int args, const char** argv)
{
    auto builder = std::make_shared<Hypodermic::ContainerBuilder>();

    /// CASE1: this works if I resolve from container instead of nested container
    // using resolved_type = service;
    // builder->registerType<service>().singleInstance();

    /// CASE2: this works if I resolve from container instead of nested container
    // using resolved_type = interface;
    // builder->registerType<service>().as<interface>().singleInstance();

    /// CASE3: this works for both nested container and container
    // using resolved_type = interface;
    // builder->registerInstance(std::make_shared<service>()).as<interface>();

    /// CASE4: this works for both nested container and container
    using resolved_type = service;
    builder->registerInstance(std::make_shared<service>());

    auto container = builder->build();

    {
        auto nested_builder = std::make_shared<Hypodermic::ContainerBuilder>();
        auto nested_container = nested_builder->buildNestedContainerFrom(*container);
        auto service0 = nested_container->resolve<resolved_type>();
        service0->get_value() = true;
    }

    {
        auto nested_builder = std::make_shared<Hypodermic::ContainerBuilder>();
        auto nested_container = nested_builder->buildNestedContainerFrom(*container);
        auto service0 = nested_container->resolve<resolved_type>();
        assert(service0->get_value());
    }

    {
        auto service0 = container->resolve<resolved_type>();
        assert(service0->get_value());
    }

    return 0;
}

All of these cases work fine when I resolve the resolved_type from container instead of nested_container. However when resolving from nested_container cases 1 and 2 fail both of the asserts.

Pass parameters to register type

Hi,

I have function which gets 2 params (primitive types: string and char*), and need to do register type to a class where the ctor needs those 2 params.

I found other old issue (from 2015) which answers a very similar issue #13 but i'm getting exception for using it:
error: ‘IComponentContext’ has not been declared
=
^~~~~~~~~~~~~~~~~
When trying to change IComponentContext to ComponentContext i'm getting:
error: static assertion failed: Could not autowire T: you should consider registering T either by providing an instance or an instance factory

So what is the right syntax?
Thanks!

Incorrect activation hooks call order

Scenario:

  1. Specify activation hook while registering class A
  2. Register class B depending on class A
  3. Perform resolve for class B

Code example:

#include <iostream>
#include <Hypodermic/ContainerBuilder.h>
#include <Hypodermic/Container.h>

class A
{
public:
    A() { std::cout << "Create A" << std::endl; }
};

class B
{
public:
    B(const std::shared_ptr<A>&) { std::cout << "Create B" << std::endl; }
};

int main()
{
    Hypodermic::ContainerBuilder builder;
    builder.registerType<A>()
           .singleInstance()
           .onActivated([](auto&, const std::shared_ptr<A>&){
        std::cout << "Activation Hook" << std::endl;
    });
    builder.registerType<B>();

    auto container = builder.build();
    auto b = container->resolve<B>();

    return 0;
}

Expected behavior:

Create A
Activation Hook
Create B

Current behavior:

Create A
Create B
Activation Hook

Works as expected in the 416cb0c commit and earlier.

Hypodermic 2.5.3 won't link with Boost

A while back I installed your library so that I could look at the code that David Sackstein presented in his CppCon 2022 presentation 10 Tips for Cleaner C++ code.

I've been trying to get his code running under VS2022 Preview which currently fails, and so I've revisited it, as part of demonstrating to MS that the preview has now broken the code from the presentation.

I tried upgrading both of the third party libraries tl::expected and Hypodermic.

However when it came to trying to build version 2.5.3 I find it doesn't link properly, unfortunately I threw away my previous copy of your library and so I don't know what version I was working from. I looked for old .zip files and it looks like I must previously have just cloned the repository at the time, and so now I can't go back.

When I encountered the errors in VS2022, I tried again to build Hypodermic in VS2019 but the same errors occur.

[19/20] Linking CXX executable Hypodermic.Tests\Hypodermic.Tests.exe
  FAILED: Hypodermic.Tests/Hypodermic.Tests.exe 
  cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~4\2019\PROFES~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\main.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\CircularDependencyTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ContainerBuilderTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ContainerTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\DefaultConstructibleTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\FactoryTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\IsCompleteTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\MemoryTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\NamedTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\NestedContainerTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\PerformanceTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\PersistentInstanceRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ProvidedDependenciesTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ProvidedInstanceFactoryRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ProvidedInstanceRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\RegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\RuntimeRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\UseIfNoneTests.cpp.obj  /out:Hypodermic.Tests\Hypodermic.Tests.exe /implib:Hypodermic.Tests\Hypodermic.Tests.lib /pdb:Hypodermic.Tests\Hypodermic.Tests.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console -LIBPATH:C:\'Boost\boost_1_81_0\lib C:\'Boost\boost_1_81_0\lib\libboost_system-vc142-mt-gd-x64-1_81.lib  C:\'Boost\boost_1_81_0\lib\libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cmd.exe /C "cd /D C:\Dev\Libraries\Hypodermic\out\build\x64-Debug\Hypodermic.Tests && C:\Dev\Libraries\Hypodermic\out\build\x64-Debug\Hypodermic.Tests\Hypodermic.Tests""
  LINK Pass 1: command "C:\PROGRA~2\MICROS~4\2019\PROFES~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\main.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\CircularDependencyTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ContainerBuilderTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ContainerTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\DefaultConstructibleTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\FactoryTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\IsCompleteTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\MemoryTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\NamedTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\NestedContainerTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\PerformanceTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\PersistentInstanceRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ProvidedDependenciesTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ProvidedInstanceFactoryRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\ProvidedInstanceRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\RegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\RuntimeRegistrationTests.cpp.obj Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir\UseIfNoneTests.cpp.obj /out:Hypodermic.Tests\Hypodermic.Tests.exe /implib:Hypodermic.Tests\Hypodermic.Tests.lib /pdb:Hypodermic.Tests\Hypodermic.Tests.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console -LIBPATH:C:\'Boost\boost_1_81_0\lib C:\'Boost\boost_1_81_0\lib\libboost_system-vc142-mt-gd-x64-1_81.lib C:\'Boost\boost_1_81_0\lib\libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir/intermediate.manifest Hypodermic.Tests\CMakeFiles\Hypodermic.Tests.dir/manifest.res" failed (exit code 1169) with the following output:
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "void __cdecl boost::unit_test::results_reporter::set_level(enum boost::unit_test::report_level)" (?set_level@results_reporter@unit_test@boost@@YAXW4report_level@23@@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(results_reporter.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: enum boost::unit_test::log_level __cdecl boost::unit_test::unit_test_log_t::set_threshold_level(enum boost::unit_test::log_level)" (?set_threshold_level@unit_test_log_t@unit_test@boost@@QEAA?AW4log_level@23@W4423@@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(unit_test_log.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: static class boost::unit_test::unit_test_log_t & __cdecl boost::unit_test::unit_test_log_t::instance(void)" (?instance@unit_test_log_t@unit_test@boost@@SAAEAV123@XZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(unit_test_log.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::unit_test::framework::impl::master_test_suite_name_setter::master_test_suite_name_setter(class boost::unit_test::basic_cstring<char const >)" (??0master_test_suite_name_setter@impl@framework@unit_test@boost@@QEAA@V?$basic_cstring@$$CBD@34@@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(framework.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::unit_test::global_configuration::global_configuration(void)" (??0global_configuration@unit_test@boost@@QEAA@XZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: virtual __cdecl boost::unit_test::global_configuration::~global_configuration(void)" (??1global_configuration@unit_test@boost@@UEAA@XZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: virtual __cdecl boost::unit_test::lazy_ostream::~lazy_ostream(void)" (??1lazy_ostream@unit_test@boost@@UEAA@XZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(framework.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: static class boost::unit_test::lazy_ostream & __cdecl boost::unit_test::lazy_ostream::instance(void)" (?instance@lazy_ostream@unit_test@boost@@SAAEAV123@XZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(framework.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "protected: __cdecl boost::unit_test::lazy_ostream::lazy_ostream(bool)" (??0lazy_ostream@unit_test@boost@@IEAA@_N@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(framework.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: void __cdecl boost::unit_test::unit_test_log_t::set_checkpoint(class boost::unit_test::basic_cstring<char const >,unsigned __int64,class boost::unit_test::basic_cstring<char const >)" (?set_checkpoint@unit_test_log_t@unit_test@boost@@QEAAXV?$basic_cstring@$$CBD@23@_K0@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(unit_test_log.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::test_tools::assertion_result::assertion_result(bool)" (??0assertion_result@test_tools@boost@@QEAA@_N@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::test_tools::assertion_result::~assertion_result(void)" (??1assertion_result@test_tools@boost@@QEAA@XZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "bool __cdecl boost::test_tools::tt_detail::report_assertion(class boost::test_tools::assertion_result const &,class boost::unit_test::lazy_ostream const &,class boost::unit_test::basic_cstring<char const >,unsigned __int64,enum boost::test_tools::tt_detail::tool_level,enum boost::test_tools::tt_detail::check_type,unsigned __int64,...)" (?report_assertion@tt_detail@test_tools@boost@@YA_NAEBVassertion_result@23@AEBVlazy_ostream@unit_test@3@V?$basic_cstring@$$CBD@63@_KW4tool_level@123@W4check_type@123@3ZZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tools.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: static class boost::unit_test::decorator::collector_t & __cdecl boost::unit_test::decorator::collector_t::instance(void)" (?instance@collector_t@decorator@unit_test@boost@@SAAEAV1234@XZ) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(decorator.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::unit_test::test_case::test_case(class boost::unit_test::basic_cstring<char const >,class boost::unit_test::basic_cstring<char const >,unsigned __int64,class boost::function<void __cdecl(void)> const &)" (??0test_case@unit_test@boost@@QEAA@V?$basic_cstring@$$CBD@12@0_KAEBV?$function@$$A6AXXZ@2@@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl boost::unit_test::ut_detail::normalize_test_case_name(class boost::unit_test::basic_cstring<char const >)" (?normalize_test_case_name@ut_detail@unit_test@boost@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$basic_cstring@$$CBD@23@@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(class boost::unit_test::test_case *,class boost::unit_test::decorator::collector_t &,unsigned long)" (??0auto_test_unit_registrar@ut_detail@unit_test@boost@@QEAA@PEAVtest_case@23@AEAVcollector_t@decorator@23@K@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(class boost::unit_test::basic_cstring<char const >,class boost::unit_test::basic_cstring<char const >,unsigned __int64,class boost::unit_test::decorator::collector_t &)" (??0auto_test_unit_registrar@ut_detail@unit_test@boost@@QEAA@V?$basic_cstring@$$CBD@23@0_KAEAVcollector_t@decorator@23@@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: __cdecl boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(int)" (??0auto_test_unit_registrar@ut_detail@unit_test@boost@@QEAA@H@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tree.obj)
C:\Dev\Libraries\Hypodermic\boost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(boost_unit_test_framework-vc142-mt-gd-x64-1_81.dll) : error LNK2005: "public: void __cdecl boost::test_tools::tt_detail::print_log_value<bool>::operator()(class std::basic_ostream<char,struct std::char_traits<char> > &,bool)" (??R?$print_log_value@_N@tt_detail@test_tools@boost@@QEAAXAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@_N@Z) already defined in libboost_unit_test_framework-vc142-mt-gd-x64-1_81.lib(test_tools.obj)
C:\Dev\Libraries\Hypodermic\Hypodermic.Tests\Hypodermic.Tests.exe : fatal error LNK1169: one or more multiply defined symbols found
  ninja: build stopped: subcommand failed.

Current syntax for register factory with arguments

hi,
Currently i'm using a very old Hypodermic version with the following syntax:
builder.registerType< FooFactory >(CREATE(std::make_shared< FooFactory >(
INJECT(IClass1),
INJECT(IClass2)
))).as< IFooFactory >().singleInstance();
where IClass1 and IClass2 are the params to FooFactory ctor.

I'm not sure how to convert it to the current syntax (without CREATE and INJECT).
I tried builder.registerInstanceFactory and builder.registerInstance and it didn't work.
I also tried to pass the params with context.resolve / container->resolve and it didn't work.

so what should i do? thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.