Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last month.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
Improve this question
Recently I've read Mark Seemann's article about Service Locator anti-pattern.
Author points out two main reasons why ServiceLocator is an anti-pattern:
API usage issue (which I'm perfectly fine with)
When class employs a Service locator it is very hard to see its dependencies as, in most cases, class has only one PARAMETERLESS constructor.
In contrast with ServiceLocator, DI approach explicitly exposes dependencies via constructor's parameters so dependencies are easily seen in IntelliSense.
Maintenance issue (which puzzles me)
Consider the following expample
We have a class 'MyType' which employs a Service locator approach:
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
Now we want to add another dependency to class 'MyType'
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
And here is where my misunderstanding starts. The author says:
It becomes a lot harder to tell whether you are introducing a breaking change or not. You need to understand the entire application in which the Service Locator is being used, and the compiler is not going to help you.
But wait a second, if we were using DI approach, we would introduce a dependency with another parameter in constructor (in case of constructor injection). And the problem will be still there. If we may forget to setup ServiceLocator, then we may forget to add a new mapping in our IoC container and DI approach would have the same run-time problem.
Also, author mentioned about unit test difficulties. But, won't we have issues with DI approach? Won't we need to update all tests which were instantiating that class? We will update them to pass a new mocked dependency just to make our test compilable. And I don't see any benefits from that update and time spending.
I'm not trying to defend Service Locator approach. But this misunderstanding makes me think that I'm losing something very important. Could somebody dispel my doubts?
UPDATE (SUMMARY):
The answer for my question "Is Service Locator an anti-pattern" really depends upon the circumstances. And I definitely wouldn't suggest to cross it out from your tool list. It might become very handy when you start dealing with legacy code. If you're lucky enough to be at the very beginning of your project then the DI approach might be a better choice as it has some advantages over Service Locator.
And here are main differences which convinced me to not use Service Locator for my new projects:
Most obvious and important: Service Locator hides class dependencies
If you are utilizing some IoC container it will likely scan all constructor at startup to validate all dependencies and give you immediate feedback on missing mappings (or wrong configuration); this is not possible if you're using your IoC container as Service Locator
For details read excellent answers which are given below.
If you define patterns as anti-patterns just because there are some situations where it does not fit, then YES it's an anti pattern. But with that reasoning all patterns would also be anti patterns.
Instead we have to look if there are valid usages of the patterns, and for Service Locator there are several use cases. But let's start by looking at the examples that you have given.
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
The maintenance nightmare with that class is that the dependencies are hidden. If you create and use that class:
var myType = new MyType();
myType.MyMethod();
You do not understand that it has dependencies if they are hidden using service location. Now, if we instead use dependency injection:
public class MyType
{
public MyType(IDep1 dep1, IDep2 dep2)
{
}
public void MyMethod()
{
dep1.DoSomething();
// new dependency
dep2.DoSomething();
}
}
You can directly spot the dependencies and cannot use the classes before satisfying them.
In a typical line of business application you should avoid the use of service location for that very reason. It should be the pattern to use when there are no other options.
Is the pattern an anti-pattern?
No.
For instance, inversion of control containers would not work without service location. It's how they resolve the services internally.
But a much better example is ASP.NET MVC and WebApi. What do you think makes the dependency injection possible in the controllers? That's right -- service location.
Your questions
But wait a second, if we were using DI approach, we would introduce a
dependency with another parameter in constructor (in case of
constructor injection). And the problem will be still there.
There are two more serious problems:
With service location you are also adding another dependency: The service locator.
How do you tell which lifetime the dependencies should have, and how/when they should get cleaned up?
With constructor injection using a container you get that for free.
If we may
forget to setup ServiceLocator, then we may forget to add a new
mapping in our IoC container and DI approach would have the same
run-time problem.
That's true. But with constructor injection you do not have to scan the entire class to figure out which dependencies are missing.
And some better containers also validate all dependencies at startup (by scanning all constructors). So with those containers you get the runtime error directly, and not at some later temporal point.
Also, author mentioned about unit test difficulties. But, won't we have issues with DI approach?
No. As you do not have a dependency to a static service locator. Have you tried to get parallel tests working with static dependencies? It's not fun.
I would also like to point out that IF you are refactoring legacy code that the Service Locator pattern is not only not an anti-pattern, but it is also a practical necessity. No-one is ever going to wave a magic wand over millions of lines of code and suddenly all that code is going to be DI ready. So if you want to start introducing DI to an existing code base it is often the case that you will change things to become DI services slowly, and the code that references these services will often NOT be DI services. Hence THOSE services will need to use the Service Locator in order to get instances of those services that HAVE been converted to use DI.
So when refactoring large legacy applications to start to use DI concepts I would say that not only is Service Locator NOT an anti-pattern, but that it is the only way to gradually apply DI concepts to the code base.
From the testing point of view, Service Locator is bad. See Misko Hevery's Google Tech Talk nice explanation with code examples http://youtu.be/RlfLCWKxHJ0 starting at minute 8:45. I liked his analogy: if you need $25, ask directly for money rather than giving your wallet from where money will be taken. He also compares Service Locator with a haystack that has the needle you need and knows how to retrieve it. Classes using Service Locator are hard to reuse because of it.
Maintenance issue (which puzzles me)
There are 2 different reasons why using service locator is bad in this regard.
In your example, you are hard-coding a static reference to the service locator into your class. This tightly couples your class directly to the service locator, which in turns means it won't function without the service locator. Furthermore, your unit tests (and anybody else who uses the class) are also implicitly dependent on the service locator. One thing that has seemed to go unnoticed here is that when using constructor injection you don't need a DI container when unit testing, which simplifies your unit tests (and developers' ability to understand them) considerably. That is the realized unit testing benefit you get from using constructor injection.
As for why constructor Intellisense is important, people here seem to have missed the point entirely. A class is written once, but it may be used in several applications (that is, several DI configurations). Over time, it pays dividends if you can look at the constructor definition to understand a class's dependencies, rather than looking at the (hopefully up-to-date) documentation or, failing that, going back to the original source code (which might not be handy) to determine what a class's dependencies are. The class with the service locator is generally easier to write, but you more than pay the cost of this convenience in ongoing maintenance of the project.
Plain and simple: A class with a service locator in it is more difficult to reuse than one that accepts its dependencies through its constructor.
Consider the case where you need to use a service from LibraryA that its author decided would use ServiceLocatorA and a service from LibraryB whose author decided would use ServiceLocatorB. We have no choice other than using 2 different service locators in our project. How many dependencies need to be configured is a guessing game if we don't have good documentation, source code, or the author on speed dial. Failing these options, we might need to use a decompiler just to figure out what the dependencies are. We may need to configure 2 entirely different service locator APIs, and depending on the design, it may not be possible to simply wrap your existing DI container. It may not be possible at all to share one instance of a dependency between the two libraries. The complexity of the project could even be further compounded if the service locators don't happen to actually reside in the same libraries as the services we need - we are implicitly dragging additional library references into our project.
Now consider the same two services made with constructor injection. Add a reference to LibraryA. Add a reference to LibraryB. Provide the dependencies in your DI configuration (by analyzing what is needed via Intellisense). Done.
Mark Seemann has a StackOverflow answer that clearly illustrates this benefit in graphical form, which not only applies when using a service locator from another library, but also when using foreign defaults in services.
My knowledge is not good enough to judge this, but in general, I think if something has a use in a particular situation, it does not necessarily mean it cannot be an anti-pattern. Especially, when you are dealing with 3rd party libraries, you don't have full control on all aspects and you may end up using the not very best solution.
Here is a paragraph from Adaptive Code Via C#:
"Unfortunately, the service locator is sometimes an unavoidable anti-pattern. In some application types— particularly Windows Workflow Foundation— the infrastructure does not lend itself to constructor injection. In these cases, the only alternative is to use a service locator. This is better than not injecting dependencies at all. For all my vitriol against the (anti-) pattern, it is infinitely better than manually constructing dependencies. After all, it still enables those all-important extension points provided by interfaces that allow decorators, adapters, and similar benefits."
-- Hall, Gary McLean. Adaptive Code via C#: Agile coding with design patterns and SOLID principles (Developer Reference) (p. 309). Pearson Education.
I can suggest considering generic approach to avoid the demerits of Service Locator pattern.
It allows explicitly declaring class dependencies and substitute mocks and doesn't depend on a particular DI Container.
Possible drawbacks of this approach is:
It makes your control classes generic.
It is not easy to override some particular interface.
1 First Declare interface
public interface IResolver<T>
{
T Resolve();
}
Create ‘flattened’ class with implementing of resolving the most of frequently used interfaces from DI Container and register it.
This short example uses Service Locator but before composition root. Alternative way is inject each interface with constructor.
public class FlattenedServices :
IResolver<I1>,
IResolver<I2>,
IResolver<I3>
{
private readonly DIContainer diContainer;
public FlattenedServices(DIContainer diContainer)
{
this.diContainer = diContainer;
}
I1 IResolver<I1>.Resolve()
=> diContainer.Resolve<I1>();
I2 IResolver<I2>.Resolve()
=> diContainer.Resolve<I2>();
I3 IResolver<I3>.Resolve()
=> diContainer.Resolve<I3>();
}
Constructor injection on some MyType class should look like
public class MyType<T> : IResolver<T>
where T : class, IResolver<I1>, IResolver<I3>
{
T servicesContext;
public MyType(T servicesContext)
{
this.servicesContext = servicesContext
?? throw new ArgumentNullException(nameof(serviceContext));
_ = (servicesContext as IResolver<I1>).Resolve() ?? throw new ArgumentNullException(nameof(I1));
_ = (servicesContext as IResolver<I3>).Resolve() ?? throw new ArgumentNullException(nameof(I3));
}
public void MyMethod()
{
var dep1 = ((IResolver<I1>)servicesContext).Resolve();
dep1.DoSomething();
var dep3 = ((IResolver<I3>)servicesContext).Resolve();
dep3.DoSomething();
}
T IResolver<T>.Resolve() => serviceContext;
}
P.S. If you don't need to pass servicesContext further in MyType, you can declare object servicesContext; and make generic only ctor not class.
P.P.S. That FlattenedServices class could be considered as main DI container and a branded container could be considered as supplementary container.
The Author reasons that "the compiler won't help you" - and it is true.
When you deign a class, you will want to carefully choose its interface - among other goals to make it as independent as ... as it makes sense.
By having the client accept the reference to a service (to a dependency) through explicit interface, you
implicitly get checking, so the compiler "helps".
You're also removing the need for the client to know something about the "Locator" or similar mechanisms, so the client is actually more independent.
You're right that DI has its issues / disadvantages, but the mentioned advantages outweigh them by far ... IMO.
You're right, that with DI there is a dependency introduced in the interface (constructor) - but this is hopefully the very dependency that you need and that you want to make visible and checkable.
Yes, service locator is an anti-pattern it violates encapsulation and solid.
Service Locator(SL)
Service Locator solves [DIP + DI] issue. It allows by interface name satisfy needs. Service Locator can be as singleton or can be passed into constructor.
class A {
IB ib
init() {
ib = ServiceLocator.resolve<IB>();
}
}
The problem here that it is not clear which exactly classes(realizations of IB) are used by client(A).
proposal - pass parameter explicitly
class A {
IB ib
init(ib: IB) {
self.ib = ib
}
}
SL vs DI IoC Container(framework)
SL is about saving instances when DI IoC Container(framework) is more about creating instances.
SL works as a PULL command when it retrieves dependencies inside constructor
DI IoC Container(framework) works as a PUSH command when it put dependencies into constructor
I think that the author of the article shot himself on the foot in proving that it's an anti pattern with the update written 5 years later. There, it is said that this is the correct way:
public OrderProcessor(IOrderValidator validator, IOrderShipper shipper)
{
if (validator == null)
throw new ArgumentNullException("validator");
if (shipper == null)
throw new ArgumentNullException("shipper");
this.validator = validator;
this.shipper = shipper;
}
Then below is said:
Now it's clear that all three object are required before you can call the Process method; this version of the OrderProcessor class advertises its preconditions via the type system. You can't even compile client code unless you pass arguments to constructor and method (you can pass null, but that's another discussion).
Let me stress the last part again:
you can pass null, but that's another discussion
Why that is another discussion? That is a huge deal. An object that receives its dependencies as arguments fully depends on the previous execution of the application (or tests) to provide those objects as valid references/pointers. It is not "encapsulated" in the terms that the author expressed, as it depends on a lot of external machinery to run in a satisfactory manner for the object to be constructed at all, and later to work properly when it needs to use the other class.
The author claims that it's the Service Locator which is not encapsulated because it's depending on an additional object that you can't isolate from on the tests. But that other object could very well be a trivial map or vector, so it's pure data with no behavior. In C++, for example, containers are not part of the language, so you rely on containers (vectors, hash maps, strings, etc.) for all non-trivial classes. Are they not isolated because rely on containers? I don't think so.
I think that both using manual dependency injection or a service locator the objects are not really isolated from the rest: they need their dependencies, yes or yes, but are provided in a different way. I for one think that a locator even helps with the DRY principle, as it's error prone and repetitive to pass over and over pointers through the application. The service locator can also be more flexible in that an object might retrieve its dependencies when needed (if needed), not only via the constructor.
The problem of the dependencies not being explicit enough via the constructor of the object (on an object using the service locator) is solved by the very thing I stressed out before: passing null pointers. It can be even used to mix and match both systems: if the pointer is null, use the service locator, otherwise, use the pointer. Now it is enforced via the type system, and it's obvious to the user of the class. But we can do even better.
One additional solution that is surely doable with C++ (I don't know about Java/C#, but I suppose it could be done as well), is to write a helper class to be instantiated like LocatorChecker<IOrderValidator, IOrderShipper>. That object could check on it's constructor/destructor that the service locator holds a valid instance of the required classes, hence, being also less repetitive than the example provided by Mark Seeman.
I'm currently building an application, and as it stands I have a single service for each controller (the service handles the business logic for the controller). Each service has it's own dbcontext.
I've recognised that several services need to perform the same functions (retrieve the same lists of data from the database and perform the same logic on them before returning them). So ideally I need a way for the services to access common functions.
My first thought is to create a simple helper class that each service could use, with simple functions that take a dbcontext as one of the parameters, so that the functions could perform database queries as well as logic and return the result.
Is this a good idea? Would I run into problems by structuring my code this way, or is there a better more robust and accepted approach I should take?
I'd say you're on the right track, but go one step further with the single responsibility principle. http://blog.codinghorror.com/curlys-law-do-one-thing/. It's a proven strategy for keeping code clean. I avoid "helper" classes per say. They can get messy by having too many responsibilities. Instead I try to really think about what my class should do. Then I give it a really good name to remind me that it only does that one thing.
The fact that your services each have their own Db Context can be a problem. Just make sure that if you call upon more than 1 dependent service that you pass in the same Db context to them all. If your object graph is large, a container like AutoFac will be a big help.
Is the data being returned the same? Are they using their own unique DB context or is it the same DB context?
Generally I would recommend avoiding creating a helper class. Generally a helper class is used to manipulate an object(s) rather than perform a database query.
Based on your comment there are two ways you could achieve this, one easier than the other.
Option 1:
If your application really is a simple one that you're not too concerned about doing things the 'correct' way then you could simply create base service class and update your services to extend it, and move your common database access into the base class, like so:
abstract class BaseService
{
...
public ICollection<ExampleRecord> GetDatabaseRecords()
{
using (var context = new ApplicationDbContext())
{
/* Your DbContext code */
}
return databaseRecords;
}
...
}
Then extend BaseService like so:
public class ExampleService : BaseService
{
...
public ICollection<ExampleRecord> GetRecords()
{
return this.GetDatabaseRecords();
}
...
}
This would get the job done and be a better option to what you're currently doing, however it's generally not the best approach.
Optios 2:
If your application is more than a simple one and you're concerned about code maintainability then I would suggest looking into moving your database access code into a separate repository class and use an IoC container such as StructureMap to inject it the said repository into your services via dependency injection.
Personally I would recommend option 2 as it's far cleaner, more maintainable/extensible and you're not violating any of the SOLID principles.
You can use an abstract service to define a common methods
This is a good tutorial about
generic repository, services layer, IoC, unit test an entity framework
I am trying to get rid off static classes, static helper methods and singleton classes in my code base. Currently, they are pretty much spread over the whole code, especially so for the utility classes and the logging library. This is mainly due to the need for mocking ability as well as object-oriented design and development concerns, e.g. extensibility. I might also need to introduce some form of dependency injection in the future and would like to leave an open door for that.
Basically, the problem I have encountered is about the method of passing the commonly used references around. These are objects that are used by almost every class in the code base, such as the logging interface, the utility (helper) class interface and maybe an instance of a class that holds an internal common state for the assembly which most classes relate to.
There are two options, as far as I'm aware. One is to define a class (or an interface) that stores the common references, a context if you will, and pass the context to each object that is created. The other option is to pass each common reference to almost every class as a separate parameter which would increase the number of parameters of the class constructors.
Which one of these methods is better, what are the pros and cons of each, and is there a better method for this task?
I generally go with the context object approach, and pass the context object either to an object's constructor, or to a method -- depending on which one makes the most sense.
The context object pattern can take a few forms.
You can define an interface that has exactly the members you need, or you can generate a sort of container class. For example, when writing loosely-coupled components, I tend to have each component I implement have a matching interface, so that it can be reimplemented if desired. Then I register the objects on a "manager" object, something like this:
public interface IServiceManager
{
public T GetService<T>();
public T RequireService<T>();
public void RegisterService<T>(T service);
public void UnregisterService<T>(T service);
}
Behind the scenes there is a map from type to object, which allows me to extremely quickly assemble a large set of diverse components into a working whole. Each component asks for the others by interface, and the manager object is what glues them together. (If you correctly author your components, you can even swap out one service for another while the process is running!)
One would register a service something along these lines:
class FooService : IFooService { }
// During process start-up:
serviceManager.RegisterService<IFooService>(new FooService());
There is more overhead with this approach than with the flat-interface approach due to the dictionary lookup, but it has allowed me to build very sophisticated systems that can be easily redeployed with different service implementations. (And, as is usual, any bottlenecks I encounter are never in looking up a service object from a dictionary, but somewhere else such as the database.)
You're going to get varied opinions, but generally passing a separate parameter to the constructor for each dependency is preferred for a few reasons:
It clearly defines the actual dependencies for a class - with a "context" you don't know which parts of the context are used without digging into the code.
Generally having a lot of parameters to a constructor is a design smell, so using constructor injection helps you sniff out design flaws.
When testing you can mock out individual dependencies versus having to mock an entire context
I would suggest passing as a parameter to the constructor. This has great advantage for both dependency injection and unit testability ( mocking).
I've been using IoC (mostly Unity) and Dependency Injection in .NET for some time now and I really like the pattern as a way to encourage creation of software classes with loose coupling and which should be easier to isolate for testing.
The approach I generally try to stick to is "Nikola's Five Laws of IoC" - in particular not injecting the container itself and only using constructor injection so that you can clearly see all the dependencies of a class from its constructor signature. Nikola does have an account on here but I'm not sure if he is still active.
Anyway, when I end up either violating one of the other laws or generally ending up with something that doesn't feel or look right, I have to question whether I'm missing something, could do it better, or simply shouldn't be using IoC for certain cases. With that in mind here are a few examples of this and I'd be grateful for any pointers or further discussion on these:
Classes with too many dependencies. ("Any class having more then 3 dependencies should be questioned for SRP violation"). I know this one comes up a lot in dependency injection questions but after reading these I still don't have any Eureka moment that solves my problems:
a) In a large application I invariably find I need 3 dependencies just to access infrastructure (examples - logging, configuration, persistence) before I get to the specific dependencies needed for the class to get its (hopefully single responsibility) job done. I'm aware of the approach that would refactor and wrap such groups of dependencies into a single one, but I often find this becomes simply a facade for several other services rather than having any true responsibility of its own. Can certain infrastructure dependencies be ignored in the context of this rule, provided the class is deemed to still have a single responsibility?
b) Refactoring can add to this problem. Consider the fairly common task of breaking apart a class that has become a bit big - you move one area of functionality into a new class and the first class becomes dependent on it. Assuming the first class still needs all the dependencies it had before, it now has one extra dependency. In this case I probably don't mind that this dependency is more tightly coupled, but its still neater to have the container provide it (as oppose to using new ...()), which it can do even without the new dependency having its own interface.
c) In a one specific example I have a class responsible for running various different functions through the system every few minutes. As all the functions rightly belong in different areas, this class ends up with many dependencies just to be able to execute each function. I'm guessing in this case other approaches, possibly involving events, should be considered but so far I haven't tried to do it because I want to co-ordinate the order the tasks are run and in some cases apply logic involving outcomes along the way.
Once I'm using IoC within an application it seems like almost every class I create that is used by another class ends up being registered in and/or injected by the container. Is this the expected outcome or should some classes have nothing to do with IoC? The alternative of just having something new'd up within the code just looks like a code smell since its then tightly coupled. This is kind of related to 1b above too.
I have all my container initialisation done at application startup, registering types for each interface in the system. Some are deliberately single instance lifecycles where others can be new instance each time they are resolved. However, since the latter are dependencies of the former, in practice they become a single instance too since they are only resolved once - at construction time of the single instance. In many cases this doesn't matter, but in some cases I really want a different instance each time I do an operation, so rather than be able to make use of the built in container functionality, I'm forced to either i) have a factory dependency instead so I can force this behaviour or ii) pass in the container so I can resolve each time. Both of these approaches are frowned upon in Nikola's guidance but I see i) as the lesser of two evils and I do use it in some cases.
In a large application I invariably find I need 3 dependencies just to access infrastructure (examples - logging, configuration, persistence)
imho infrastructure is not dependencies. I have no problem using a servicelocator for getting a logger (private ILogger _logger = LogManager.GetLogger()).
However, persistence is not infrastructure in my point of view. It's a dependency. Break your class into smaller parts.
Refactoring can add to this problem.
Of course. You will get more dependencies until you have successfully refactored all classes. Just hang in there and continue refactoring.
Do create interfaces in a separate project (Separated interface pattern) instead of adding dependencies to classes.
In a one specific example I have a class responsible for running various different functions through the system every few minutes. As all the functions rightly belong in different areas, this class ends up with many dependencies just to be able to execute each function.
Then you are taking the wrong approach. The task runner should not have a dependency on all tasks that should run, it should be the other way around. All tasks should register in the runner.
Once I'm using IoC within an application it seems like almost every class I create that is used by another class ends up being registered in and/or injected by the container.*
I register everything but business objects, DTOs etc in my container.
I have all my container initialisation done at application startup, registering types for each interface in the system. Some are deliberately single instance lifecycles where others can be new instance each time they are resolved. However, since the latter are dependencies of the former, in practice they become a single instance too since they are only resolved once - at construction time of the single instance.
Don't mix lifetimes if you can avoid it. Or don't take in short lived dependencies. In this case you could use a simple messaging solution to update the single instances.
You might want to read my guidelines.
Let me answer question 3. Having a singletons depend on a transient is a problem that container profilers try to detect and warn about. Services should only depend on other services that have a lifetime that is greater than or equals to that of their own. Injecting a factory interface or delegate to solve this is in general a good solution, and passing in the container itself is a bad solution, since you end up with the Service Locator anti-pattern.
Instead of injecting a factory, you can solve this by implementing a proxy. Here's an example:
public interface ITransientDependency
{
void SomeAction();
}
public class Implementation : ITransientDependency
{
public SomeAction() { ... }
}
Using this definition, you can define a proxy class in the Composition Root based on the ITransientDependency:
public class TransientDependencyProxy<T> : ITransientDependency
where T : ITransientDependency
{
private readonly UnityContainer container;
public TransientDependencyProxy(UnityContainer container)
{
this.container = container;
}
public SomeAction()
{
this.container.Resolve<T>().SomeAction();
}
}
Now you can register this TransientDependencyProxy<T> as singleton:
container.RegisterType<ITransientDependency,
TransientDependencyProxy<Implementation>>(
new ContainerControlledLifetimeManager());
While it is registered as singleton, it will still act as a transient, since it will forward its calls to a transient implementation.
This way you can completely hide that the ITransientDependency needs to be a transient from the rest of the application.
If you need this behavior for many different service types, it will get cumbersome to define proxies for each and everyone of them. In that case you could try Unity's interception functionality. You can define a single interceptor that allows you to do this for a wide range of service types.
More specifically, What's the best approach for classes where state matters, within an application which implements Dependency Injection.
Say I need access to an object that's in a particular state. For example, this object might have been initiated in a different thread, or by a process I have no control over.
A good example of an object like this that already exists in .NET is the HttpContext.
In this case, Microsoft decided to go with the Static approach, so I just say:
var currentObj = HttpContext.Current;
And this gives me a particular instance of an object without having to worry where it came from.
The problem with the Static approach is that it doesn't play very nicely with dependency injection.
The other option is to configure your certain class as a Singleton in your IoC Container. This means that you can inject it, and depending on the current IoC Container config it'll be the correct instance of the class.
However, the downfall of this approach is that the stateful importance of the object is no longer explicit in the code, it's not obvious by looking at it. With the Static class used to access and instance it's more clear that the state is important. Maybe that doesn't matter though.
So, is there a pattern that helps me out here?
Context:
For context, I'm working on an application which has many instances of a class performing IO operations. They exists within their own threads.
I want to be able to interact with those objects (background tasks) via a web interface, so a Controller. I want to be able to interrogate them, and manipulate them etc.
Update:
Sorry, I think my use of the term "stateful" is a bit misleading. let me explain some thing:
"state" is probably the wrong word. I mean communicating with an object whereby I don't have control over it's lifecycle.
It is funny that I use "stateful" when talking about static classes. That's why I gave the HttpContext example, as that exactly what it does. The Current property gets you a very specific instance, not any new instance.
When I say that static doesn't play nice with DI, I meant, you can't inject Static classes. I could create a wrapper, yes, but I'm just pushing the problem elsewhere no?
I should have been more clear about my definition of Singleton. I meant a Singleton lifestyle, as defined in an IoC Container.
I always prefer Singleton over static. In fact, I almost never use statics in my own classes.
True singletons and static classes are both very difficult to write automated tests against. Do you mean a single instance looked up at runtime? That would make sense to me but I don't know the right construct to use in C#. The analog in Java is JNDI.
Neither or both. Presuming the stateful dependency is thread-safe the better approach is to build at least a basic layer of abstraction around said dependency then inject said abstraction into your classes. Singleton vs static becomes pretty immaterial then.