Reputation:
I might be overthinking this. I hope so.
In our .Net 4.5, C# 5 Windows service, we're using Castle Windsor 3.2 with the CollectionResolver
installed. We have an interface IEncryptionService
that does what you'd expect, and two classes implement that interface. The service needs to integrate and bridge two other systems, by decrypting data from one and re-encrypting it for the other.
Both implementations have names according to their target system.
Component.For<IEncryptionService>()
.ImplementedBy<System1EncryptionService>()
.Named("system1-encryption")
.LifestyleTransient(),
Component.For<IEncryptionService>()
.ImplementedBy<System2EncryptionService>()
.LifestyleTransient()
.Named("system2-encryption"));
The Windows service class uses constructor injection to receive an array of type IEncryptionService[]
. Both of the encryption classes are being injected.
Therein lies the problem: I need to use one implementation for one system, and the other for the other. The way I've implemented it thus far, they're indistinguishable from each other.
What is the solution here? A typed factory seems like an anti-pattern covering up an architectural flaw. But its the only thing I've come up with. I've named my components; can I take advantage of that in other components? Or should I just forget injection and instantiate them directly?
I figure this sort of situation happens often enough that there's probably a standard way of handling it.
Upvotes: 2
Views: 183
Reputation: 6181
When you register your component which depends on the two, you specify the names of the arguments corresponding to the injected classes in the Compnent.For
line:
Component.For<IServiceUsingTheEncryption>()
.ImplementedBy<ServiceUsingTheEncryption>()
//.LifestyleOfYourChoosing
.ServiceOverrides(
ServiceOverride.ForKey("encryptionService1").Eq("system1-encryption"),
ServiceOverride.ForKey("encryptionService2").Eq("system2-encryption"));
And in the ctor
of your ServiceUsingTheEncryption, you would specify the arguments as such:
public ServiceUsingTheEncryption(IEncryptionService encryptionService1, IEncryptionService encryptionService2) {
// ...
}
Upvotes: 1