One of our company's products is composed of many small web-applications and a windows service, a.k.a. components, each potentially residing in a different computer. One of them is a WebForms project, which serves as the configuration hub for all the others.
We are designing a feature now to expose general information of a component. Imagine a simple interface like this for instance:
public interface IStatistics
{
Statistics GetStatistics();
}
We want to use this same interface on all components, so this is centralized on a common, shared assembly. The implementation will initially be the same also, so it is in this same assembly, alongside the interface.
The idea then is to expose a Wcf service on each component, using both the implementation and interface on the common assembly. The implementation uses environmental classes that return different things depending on where they are running, like local machine time.
The problem I would like to solve elegantly is how to pass to the webform all implementations of every component, using the same interface.
We currently use Unity, but I suppose I would face the same problem with any other DI solution. I would like to inject 5 implementations of this same interface (one for each component), and be able to differentiate them by component (think a Dictionary<Component, IStatistics>
, where Component
is an Enum
). This is needed because there will be a dropdown on the page to select which component's information is visible, and the page would then call the correct implementation to retrieve the results.
I know I can use named registrations for all implementations and then inject them. Unfortunatelly, this would lead me to:
- Have 5 different parameters on the page, each pointing to a component
- Register each implementation on the container with a different name
- Explicitly register my webform on the container, with a custom InjectionConstructor specifying each registered interface, in the correct order, for the page injection method
I know Unity has a ResolveAll method and thus allows one to receive a IStatistics[]
or IEnumerable<IStatistics>
, but then I won't be able to differentiate them.
I think MEF solves this brilliantly with the concept of Metadata interfaces. Perhaps going MEF on this would be a way to solve this issue? I think it would be inappropriate here because these are wcf proxies we are talking about, I can't see how this would integrate with MEF at all.
Maybe using a factory would be a better strategy, but I fail to see how I'll inject the services on the factory also, so the problem would persist.
IStatistics
implementations with aDisplayNameAttribute
? You can let your factory read those attributes and return anIEnumerable<KeyValuePair<string, IStatistics>>
or something similar. – HardlyIEnumerable
. The page itself knows that each parameter corresponds to a certain component, and associates it with an enum (aDictionary<Enum, Proxy>
. This enum value is what is displayed on the dropdown, and serves as a key to find the implementation when the service needs to be computed. Ideally, this would all be dynamic I think: the page would get all implementations, and them somehow show all possibilities on the dropdown, which in turn would call the correct service. – Ottoman