boost-ext / di

C++14 Dependency Injection Library
https://boost-ext.github.io/di
1.13k stars 136 forks source link

DI Runtime Injector fails to compile for bind to a value #535

Open hanexthink opened 2 years ago

hanexthink commented 2 years ago

Expected Behavior

Should compile

Actual Behavior

/Users/hafshari/.conan/data/di/1.2.0/jenkins-clt/stable/package/964905e09401b68ee5f6b695b187d4fa9eb760c2/include/boost/di/extension/providers/runtime_provider.hpp:125:14: error: call to member function 'make' is ambiguous return make(binding); ^~~~~~~ main.cpp:15:11: note: in instantiation of function template specialization 'boost::di::extension::detail::injector<boost::di::extension::assert_error_policy, boost::di::extension::shared_config>::install<boost::di::core::dependency<boost::di::scopes::instance, A>, 0>' requested here injector.install(bind.to(A(1))); ^ /Users/hafshari/.conan/data/di/1.2.0/jenkins-clt/stable/package/964905e09401b68ee5f6b695b187d4fa9eb760c2/include/boost/di/extension/providers/runtime_provider.hpp:158:8: note: candidate function [with T = A, TBinding = boost::di::core::dependency<boost::di::scopes::instance, A>] auto make(const TBinding &) -> decltype(make_impl(typename ctor_traits::type{})) { ^ /Users/hafshari/.conan/data/di/1.2.0/jenkins-clt/stable/package/964905e09401b68ee5f6b695b187d4fa9eb760c2/include/boost/di/extension/providers/runtimeprovider.hpp:163:8: note: candidate function [with T = A, TBinding = boost::di::core::dependency<boost::di::scopes::instance, A>] auto make(const TBinding &binding) -> decltype(new T{binding.object}) { ^ 1 error generated. make: *** [main] Error 1

Steps to Reproduce the Problem

  1. You could verify the issue compiling the following source code

include <boost/di.hpp>

include <boost/di/extension/providers/runtime_provider.hpp>

using namespace boost::di;

struct A { A(int) {}; virtual int now() {return 1;}; };

int main() { auto inj = make_injector(); extension::runtime_injector injector; injector.install(bind.to(A(1))); return 0; }

1. 1.

Specifications

  • Version: v1.2.0
  • Platform: macOS Monterey 12.1
  • Subsystem:
xoltar commented 2 years ago

This code doesn't look valid to me. You have to tell bind what you're binding, with a type argument. This version builds and runs on latest MacOS 12.4.

#include <boost/di.hpp>
#include <boost/di/extension/providers/runtime_provider.hpp>
#include <iostream>

using namespace boost::di;

struct A {
  A(int) {};
  virtual int now() {return 1;};
};

int main(int argc, char** argv)
{
  extension::runtime_injector injector;
  injector.install(bind<A>.to(new A(1)));

  auto a1 = injector.create<A>();
  std::cout << "now: " << a1.now() << std::endl;
  return 0;
}
hanexthink commented 2 years ago

Hi @xoltar , thanks for your prompt reply the code that you mentioned does work. But I noticed that we can't still bind to an instance where its lifetime is controlled by the user in case of using a runtime dependency injector. Can we actually pass a defined instance to a runtime injector?

include <boost/di.hpp>

include <boost/di/extension/providers/runtime_provider.hpp>

include

using namespace boost::di;

struct A { A(int i) : m_i(i) {}; int now() const {return m_i;}; int m_i; };

int main(int argc, char** argv) { extension::runtime_injector injector; A b(1); injector.install(bind.to(&b));

std::cout << "now: " << b.now() << std::endl; const A &a1 = injector.create<A &>(); a1.now(); std::cout << "now: " << a1.now() << std::endl; return 0; }