4

I have already done the following:

  1. Register an instance of my Logger in unity via a ILogger interface.
  2. Created an interface, ILoggableObject, that has a method, Hook(ILogger logger), to inject my logger.

I would like to accomplish this:

Everytime I ask for any resolution from unity, if that object implements ILoggableObject, automatically inject the ILogger interface via the Hook method.

I think this is possible via interception or policies?

Any help would be awesome.

poindexter12
  • 1,775
  • 1
  • 14
  • 20
  • 3
    Why don't you use the constructor injection, which is the default mechanism? Simply rename the `Hook` method to a public constructor (with the same arguments). – Steven Dec 06 '10 at 16:10
  • Why not just pass ILogger into whatever objects ctor that needs to use the logging behavior? – Aaron McIver Dec 06 '10 at 16:11
  • That is how I was doing it. The problem with that approach is when your objects start using multiple interfaces, you end up with a constructor that has 10 parameters. Then, another developer who wants to inherit from that base class has to supply all of the constructor parameters that he / she has no need to see. – poindexter12 Dec 06 '10 at 16:15
  • You can use Named parameter for calling constructor to avoid this. – Saeed Amiri Dec 06 '10 at 16:34
  • @Saeed, I'm not really clear on how a named parameter would avoid adding a parameter to my constructor. – poindexter12 Dec 06 '10 at 16:35
  • 5
    @poindexter12: You should never have a constructor that accepts 10 parameters, 5-6 at most. If you do, then theres clearly something wrong with it. And a class like that should be refactored into smaller parts. – Robin Orheden Dec 06 '10 at 16:41
  • @Robin, this is EXACTLY what I am trying to do. I have a ILogger that I want all of my classes to have access to. The logging functionality is isolated in a logging class. Unfortunately, I have some other utilities (dialogs, errors, etc) which are also isolated in other classes. I don't want to pass them in the constructor, I just wanted them inject for free into a base class so nobody else has to be concerned about them, they just use it and it works. – poindexter12 Dec 06 '10 at 17:01

3 Answers3

2

What you are looking for is TypeInterception in Unity. See here: http://msdn.microsoft.com/en-us/library/ff660861(PandP.20).aspx

Also here http://msdn.microsoft.com/en-us/library/ff660848(v=PandP.20).aspx

You want to intercept the call to the constructor and inject the Logger on behalf of the calling code without them being any wiser.

While I haven't done it before I believe you can do what you want using Intercept.NewInstance() http://msdn.microsoft.com/en-us/library/ff662093(PandP.20).aspx

Brad Cunningham
  • 6,402
  • 1
  • 32
  • 39
1

That is a horrible way to (attempt to) do Dependency Injection. Use Constructor Injection instead and inject (via the constructor) the ILogger into the consumer that right now has the Hook method.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • This doesn't answer my question at all. While I appreciate the feedback, I am converting away from that method because of my comment above. – poindexter12 Dec 06 '10 at 16:17
  • 2
    However, that reason is a fallacy: too many constructor arguments aren't an indication that Constructor Injection is at fault, but rather that your class has too many responsibilities: http://stackoverflow.com/questions/2420193/dependency-injection-constructor-madness/2420245#2420245 – Mark Seemann Dec 06 '10 at 17:53
  • Okay, I read your blog post. It's great. I agree with all of your principles. I don't think you are attempting to answer my question though. While you like constructor injection, others may like property or method injection. The principal is the same. I agree that it would be nice for me to aggregate all of my ancillary services into one aggregate service. I will look into doing this immediately. My question still stands. If I have one aggregate service that I would like injected automatically via a method or property, how can I do this automatically? – poindexter12 Dec 06 '10 at 18:45
  • 2
    I'm sorry that I wasn't more constructive, but it looks like you got the answer you were looking for. For the record, though, I don't agree that the choice between Constructor, Property or Method Injection is a matter of taste. They are each appropriate in different situations. – Mark Seemann Dec 07 '10 at 09:22
0

While I really like Unity and IoC/DI, I'm not sure that it is the right tool to accomplish what you want to do.

You might consider looking at aspect-oriented programming using PostSharp or a similar tool. This would allow you to add logging or other cross-cutting concerns without changing the classes being instrumented.

TrueWill
  • 25,132
  • 10
  • 101
  • 150