1

When setting a property via Dependency Injection (in this case a logging dependancy) is it "normal" to make the getter protected so that objects outside of the dependant object cannot call that property?

i.e.

public ILogger Logger { protected get; set; }

vs

public ILogger Logger { get; set; }

(I'm actually using null object pattern in these but that's beside the point).

I dont want to use constructor injection and yet via public property injection, it's not "right" for any other object to call this object's logger.

So above is what im going with but it does seem weird.

Steven
  • 166,672
  • 24
  • 332
  • 435
rism
  • 11,932
  • 16
  • 76
  • 116

3 Answers3

1

Why do you need a getter for the logger at all?

Objects that you inject should be implementation details of the thing that they are injected into. So in general you should just have a setter for such items.

WW.
  • 23,793
  • 13
  • 94
  • 121
  • Right. Good point. So you're saying just set a private var via the Setter and be done with it? – rism Oct 12 '12 at 04:38
  • Yes. And I would make a setter rather than rely on sneakiness from your DI container to set the value. This will make it easier when you write a test. – WW. Oct 12 '12 at 08:11
  • An property with an private setter is awkward. Why not make it a `SetLogger(ILogger logger)` method? – Steven Oct 12 '12 at 08:31
1

It doesn't matter that you have a public getter. Your implementation should implement an interface and consumers should depend on the interface, not the implementation. Because your Logger property is defined on the implementation, consumers will not have access to it. So there is no problem in having both a public getter and setter.

However, since you are already talking about the Null Object pattern, I assume that the logger is always injected. In that case, why not simply use constructor injection? Properties can be used for optional dependencies, but because of the use of the Null Object pattern, there is hardly ever a reason to define a property. If you find yourself defining a property because you want this logging dependency to be available for many types, please ask your self: Aren't I logging too much?

Community
  • 1
  • 1
Steven
  • 166,672
  • 24
  • 332
  • 435
  • Im using constructor injection for class and service libraries to decouple from Unity as I will likely / do use these libraries in other projects. (The dependancy attribute is required for property injection within Unity and I dont want to have to reference Practices assemblies). Within the shell and BI tho Im really only using Unity to inject logging and exception handling and it's my preference that this is largely invisible. Beyond that i just use factories. If i use contructor injection with Unity it seems I have to start overriding constructor params for non DI params. Gets to be a mess. – rism Oct 12 '12 at 10:16
  • That fact that Unity needs the attribute does make constructor injection a better choice, since this saves you from letting the reusable library take a dependency on Unity. If you are doing a lot of logging and exception handling in many classes, my old argument still stands. Think hard whether you really need logging and exception handling in that many classes. – Steven Oct 12 '12 at 11:17
  • I always try to prevent injecting both primitives and dependencies into a single constructor. I either group configuration primitives in its own type (that can be injected) or move those primitives to... (yes) properties :-). In my experience, the number of classes in the system that really need (configuration) primitives is rather small. If it isn't (for instance because you inject a connection string in many instances) you are probably missing an abstraction somewhere. Unforunately, I don't believe that there is an easy way to register primitive properties with Unity. – Steven Oct 12 '12 at 11:21
0

Generally, the getter methods are marked public (though there are purists who avoid getters also and expose well-defined actions on the object as methods) and setter methods are either avoided or marked protected/private only for the DI frameworks to be able to set the value on an object, after constructing the object using the no-arg default constructor. DI frameworks are capable of accessing protected/private methods using reflection, so the purpose to not expose setters would also be addressed.

Vikdor
  • 23,934
  • 10
  • 61
  • 84
  • Ok, i think I got that. Im using Unity and all the Setters in examples are public so I just assumed setters had to be public. Will test now. Ifigured it was good practice to have something public however (even just the setter) otherwise how does a consumer know that the class is expecting a logger? If both getter and setter are protected private, it doesn't seem like the interface is self explanatory. You'd just have to "know" that it's logger is DI'd becuase the interface of the class wouldn't tell you . – rism Oct 12 '12 at 04:41
  • Oh! thanks for the response. Java based DI framework, Spring, can access protected/private methods as well. – Vikdor Oct 12 '12 at 11:35