1

I found this line in an old branch and, as I have a lot of respect for the (unreachable) author, I'm trying to make sense of one specific line, more precisely the lambda at the end:

container.Register(Of ServiceStack.Configuration.IResolver)(Function(x) x)

container is a Funq.Container through ServiceStack. The intellisense tells me that the lambda is filling in for a (factory As Func(Of Funq.Container, ServiceStack.Configuration.IResolver)).

There is two things that I can assume about the author: he's better coder than I am, and he may have left this unfinished. For now I'm guessing that this lambda was deliberate and not some unfinished line with no clear intent, but so far nobody could help me understand why.

Craig
  • 2,248
  • 1
  • 19
  • 23
laancelot
  • 3,138
  • 2
  • 14
  • 21
  • Does the `Register` method introduce deferred execution? – Parrish Husband Oct 07 '20 at 19:59
  • In a sense, yes, as we're registering class for later autowire at this point. – laancelot Oct 07 '20 at 20:01
  • If I remember my `Func` template argument order correctly, that takes a `Funq.Container` as an argument and returns a `ServiceStack.Configuration.IResolver` as a return value. In order for this to be allowed, `Funq.Container` must itself implement that interface, and then this works out to be a trivial conversion (that the overall system would allow to be written differently to be nontrivial). – Craig Oct 07 '20 at 20:06
  • @Craig I'm not sure I understand the last part, and how the lambda is used in relation with it. – laancelot Oct 07 '20 at 20:20
  • The lambda appears to be used because it's customary to provide a factory function in registration. In this case, the factory function is that the container is itself the resolver (effectively it's doing a type cast). I'm not sure I understand why the container itself will be the `IResolver` implementation, though. I'd have to look at ServiceStack, but that's proprietary. – Craig Oct 07 '20 at 20:54
  • 1
    @Craig That makes a lot of sense. If I get it right, the container, which implements `IResolver`, would register itself as the `IResolver`, the lambda being the factory (which in practice always gives the same instance: the container). – laancelot Oct 07 '20 at 21:02
  • Yes, that's exactly what I'm saying. – Craig Oct 07 '20 at 21:12
  • @Craig Great! I suggest that you make this insight as an answer so I can mark it as solved (if you don't want to it's fine, I'll do it later). – laancelot Oct 07 '20 at 21:25

1 Answers1

2

The container is a dependency injection container. Code elsewhere will ask the container for instances of interfaces. The code here is registration code, which is telling the container how to provide an IResolver. Furthermore, it's designed to accept a factory function; resolution later will call the function to product the requested IResolver.

In this case, it appears that the container itself implements IResolver. The lambda is a function that returns its argument, so it's trivial; its argument is a Funq.Container and it returns a ServiceStack.Configuration.IResolver, so the only way this can compile is if the container implements that interface.

Thus: The container implements IResolver. The code registers a factory function which always returns back the container itself when called.

It seems rather odd to do. I don't know ServiceStack at all, so I'm not sure why it's done this way.

Craig
  • 2,248
  • 1
  • 19
  • 23