Setter injection or environment context template

I have some global components, I'm not sure how to place them in the design. For example:

  • Settings class: it matches the initial settings of the program, it can be app.config (1way), web.config (1way), hard-coded values ​​(1way) or sqldb (2way) per scene.

  • Language class: it contains different language sets, and again I may have some resx (1way) files, hard-coded values ​​(1way) or sqldb (2way).

The first question is whether I should create setter properties depending on the injection (I use Windsor):

public ISettings Settings {set;} public ILanguage Language {set;} 

Or should I make them the surrounding context:

 string DoSomethingAndReportIt() { //do something ... var param = Settings.Current.SomeParam; //report it ... return Language.Current.SomeClass_SomeMethod_Job_Done; } 

I notice that there are several components in the .net library that actually use the surrounding context template, for example. System.Security.Principal, System.Web.ProfileBase, System.Thread.CurrentCulture ...

Do you think it’s not harmful that my global classes, such as Settings and Language, be surrounding context classes? If not, why is DI preferable? Do they get more benefits in unit testing than the environment?

Second question: if DI is better (I feel like a DI pattern is preferable), what is a good way to proxy existing surrounding classes like Security.Principal or Profile to follow a DI pattern?

+8
c # design-patterns dependency-injection
source share
1 answer

The surrounding context is fine when you need to implement functionality spanning multiple layers. (In your case, you say that these two objects are global). This functionality is known as cross-reference issues . As you noticed, many classes in .NET are implemented as an ambient context , such as IPrincipal . To get a working version of your implementation of the surrounding context, you will need to have a default value for the Settings and Language objects, if they are designed as the surrounding context. My guess is that you will provide the default implementation of ILanguage and ISettings by default, and given that you will use them globally, they are good candidates for the surrounding context.

On the other hand, how often do you plan to use those objects that implement these two interfaces? And is there an existence of two objects having the value Settings != null and Language != null ? If you are really going to use them in one or two classes and / or if the existence of objects is not very important, you can go with the installation . Setter injection does not really require a default, so your object may be null .

Personally, I am not a fan of the surrounding context. However, I would use it if it turned out to be the most acceptable solution. In the case of your implementations, I would do something like this: because you will need to initialize objects that implement two interfaces once and only in one place, you can start with the surrounding context. If you realize that you are using it in a very small number of places, consider reorganizing it as a setter injection. If the existence of objects is important, consider implementing a constructor implementation .

+3
source share

All Articles