Boost logo

Boost :

From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2021-02-20 22:15:00


sob., 20 lut 2021 o 03:10 Niall Douglas via Boost <boost_at_[hidden]>
napisał(a):

> On 19/02/2021 22:20, Krzysztof Jusiak via Boost wrote:
>
> > I hope that the examples and explanation helps a bit, but if not I'm also
> > more than happy/available to have a follow-up (via zoom or similar) if
> that
> > helps (feedback could be used to improve the documentation)?
>
> Kris I speak from experience with Outcome that you're going to have to
> be much more hand holdy than that description you just gave. You'll need
> to explain things in small, baby steps, because DI is one of those
> things that nobody understands until the lightbulb switches on, and then
> they totally get it.
>
> Given that Mr. Dimov and several others have indicated they don't
> understand the motivation behind DI, if you want to see DI get into
> Boost, you're going to have to write a lot of personalised responses to
> people and keep repeating yourself to each individual in turn until
> people twig what DI is and why it's useful. I did this for Outcome, and
> whilst it was laborious at the time, I think it paid off in the end for
> everybody here.
>

Yes. My recollection of the adventure with Outcome is similar. I guess it
takes time and energy to explain one's idea to others. I imagine it is
frustrating too. One writes a library, makes an effort to share it with the
people, and the only response back is, "do more work, convince us".

> (Incidentally, I chose DI to review manage for a reason, I think this is
> the first vocabulary library we've seen presented here since Outcome. I
> am *very* much hoping its review isn't going to turn into thousands of
> emails ...)
>
>
> Andrzej, I'll give you my description of DI (which is not that of
> Boost.DI). For certain kinds of problem solution, it can make sense to
> turn inside out the traditional design of a C++ program i.e. place the
> innards on the outside, and put what is normally outside into the
> innards. You thus get an "inverted design" program.
>
> Normally that's a bad idea, because maintenance is harder, it's anti
> social to other engineers, and so on. Also, in C++, we typically use
> template techniques such as CRTP for DI, we don't typically use
> polymorphic techniques in this, but that's peculiar to C++ and not what
> most languages do because they don't have powerful enough compile time
> facilities.
>
> For complex use cases, or where a fixed ABI is absolutely needed,
> template based techniques are too painful to use to do DI, and for this
> niche use case, a common runtime framework such as that of Boost.DI lets
> arbitrary pieces of DI based code interoperate with one another in a
> composable fashion.
>
> This use case is probably even more niche than that for Outcome, which
> maybe 15% of C++ developers would ever need to consider using. For
> non-template DI, I would estimate less than 5% of C++ developers would
> ever need to consider using it.
>
> *However*, for where you do actually need runtime polymorphic DI, there
> are very few good solutions to hand in C++, unlike in other major
> languages. I think proposed Boost.DI could really fill that empty gap,
> and for those few who need that gap filled, they _badly_ need it filled.
> A standardised solution in this space would be particularly valuable.
>
>
> Just to be clear, I was talking about DI in general above, I don't know
> if Boost.DI is the correct, or sufficient, or best approach to solving
> non-template DI in C++. That's for the review here to decide.
>

So far, my understanding is the following. Please correct me, if I am
mischaracterizing the situation.

This library is not so much about Dependency Injection. Dependency
Injection is just a style of programming. The DI-library is rather about
managing the complexity that results from choosing to use Dependency
Injection.
Suppose I have a class like the following:

```
struct Point
{
  int x;
  int y;
};

struct Rect
{
  Point lowerLeft;
  Point upperRight;
};

class State
{
  Rect area;
  Point location;
  // invariant: location is inside area;
public:
  State(int left, int lo, int right, int hi, int x, int y) : area{{left,
lo}, {right, hi}}, location{x, y} {}
};

int main()
{
  State s{0, 0, 2, 2, 1, 1};
}
```

I do not like that I have to pass so many parameters, that in this
configuration can be easily confused. So, I want to apply the Dependency
Injection philosophy. I get:

class State
{
  Rect area;
  Point location;
  // invariant: location is inside area;
public:
  State(Rect a, Point loc) : area{a}, location{loc} {}
};

int main()
{
  State s{Rect{{0, 0}, {2, 2}}, Point{1, 1}};
}
```

Now, I choose to use the DI-library (this is where I have troubles with
understanding: why would I want to do that?). I get the following result:

```
int main()
{
  State s = di::make_injector().create<State>(0, 0, 2, 2, 1, 1);
}
```
And now I get back to the situation where I am passing six ints and can
easily confuse which int represents what.

I am pretty sure I am now unfairly mischaracterizing the library. But this
is what I get from the motivation and tutorial sections, and the
explanations I have seen so far. You cannot see this behavior in the
tutorial example that is using class `app`, because most of the types in
there are default-constructed or constructed from values that were
themselves (perhaps recursively) default-constructed. So it looks to me
that in order to appreciate this library, I have to make most of my types
default-constructible.

At which point am I missing something?

Regards,
&rzej;

> Niall
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk