I have a somewhat basic design question that I have not been able to find a good answer to (here, on other forums nor the books I've consulted)
I'm creating a dll and is wondering what the best way to expose its content would be. I'm aiming for a single point of entry for the apps using the dll.
The solution should adhere to the Dependency Inversion Principle (DIP) which would imply the use of an interface. But here is the kicker: the functionality of the dll requires an object to be instantiated and there must only be almost one instance at any time (kinda like a singleton though the thought sends shivers down my spine) It is this fact that I would like to spare the users of the DLL from knowing about.
Some code to explain what I would like to be able to do:
The dll:
namespace MyQuestionableDll
{
interface IMyQuestionableDll
{
public static IMyQuestionableDll Instance; // This is not allowed which makes sense
public void PressTheRedButton();
}
internal class QuestionableImplementation : IMyQuestionableDll
{
public void PressTheRedButton()
{
// Distribute Norwegian Black Metal at local school
}
}
}
And the use case:
using MyQuestionableDll;
class UnluckyAppThatIsForcedToUseQuestionableDlls
{
static void Main(string[] args)
{
IMyQuestionableDll questionableInstance = IMyQuestionableDll.Instance; // Again not allowed which still makes sense
questionableInstance.PressTheRedButton();
// or simply
MyQuestionableDll.Instance.PressTheRedButton();
}
}
An abstract class could be part of the answer but it then starts to feel like not following the DIP anymore.
Any great design insights, knowledge of best practices when making dlls or recommendations regarding Norwegian Black Metal?
If the explanation is too vague I will gladly elaborate on it.
Cheers!
- Jakob
I could imagine a two-factor approach:
A factory interface (that will create/return an instance of ...)
The API interface
For Example:
public interface IMyApiFactory
{
IMyAPI GetInstance();
}
public interface IMyAPI
{
// Whatever your API provides
}
This way you have the complete control inside your dll about how to create and reuse instances (or not).
A similar way would be some kind of Builder-Pattern:
public interface IMyApiBuilder
{
IMyApi Build();
}
public interface IMyApi
{
void PressTheRedButton();
// Whatever it does else
}
public sealed class MyAPI : IMyApi, IMyApiBuilder
{
public static IMyApiBuilder Builder = new MyAPI();
private MyAPI()
{
// CTOR ...
}
// vv Notice _explicit_ interface implemenations.
// https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation
IMyApi IMyApiBuilder.Build() { return this; }
void IMyApi.PressTheRedButton()
{
// ...
}
}
// USAGE:
IMyApi api = MyAPI.Builder.Build();
Thank you so much Fildor and ema! The ideas of adding a factory method, a factor interface or even a full-blown builder is definitely good solutions! And it got me thinking about how to incorporate them into my DLL while still sparing its users. They don't need to know that it in fact is a foul smelling factory with polluting smokestack emissions that are creating the instance :)
Then I came across Default Interface Methods and the structure of my approach ended up being
public interface MyQuestionableDll
{
static readonly MyQuestionableDll Instance = new QuestionableImplementation();
void PressTheRedButtonBelowTheDoNotPushSign();
}
internal class QuestionableImplementation : MyQuestionableDll
{
public void PressTheRedButtonBelowTheDoNotPushSign()
{
// Distribute German Volksmusik at local school
}
}
// and the use case
var questionableInstance = MyQuestionableDll.Instance;
questionableInstance.PressTheRedButtonBelowTheDoNotPushSign();
Thanks again Fildor and ema!
- Jakob
Related
Consider the following type:
class SomeType
{
public void Configure()
{
var windowsService = new ServiceController("msdtc");
windowsService.Start();
}
}
There are at least three issues.
We have implicit dependency to ServiceController.
We cannot to unit test Configure().
We have a new operator that breaks our DI strategy.
So to fix it we can extract another type and input it to our SomeType.
interface IWindowsService
{
void Start();
}
class WindowsService : IWindowsService
{
private readonly ServiceController _serviceController;
public WindowsService(string serviceName)
{
_serviceController = new ServiceController(serviceName));
}
public void Start() => _serviceController.Start();
}
class SomeType
{
private readonly IWindowsService _msdtcService;
public SomeType(Func<string, IWindowsService> createServiceCallback) //explicit dependency
{
_msdtcService = createServiceCallback.Invoke("msdtc");
}
public void Configure() => _msdtcService.Start();
}
It fixes the issues #1 and #2 but we still have a new operator in the new type WindowsService. I try to understand should I register standart ServiceController in the DI-container or use it directly as demonstrated above (by new)?
container.RegisterType<ServiceController>();
Also I am not sure whether we should try to test WindowsService or maybe it would be better to rewrite it something like this:
class WindowsService : ServiceController, IWindowsService
{
}
Since WindowsService is now just inheriting we cannot test anything here. The type is already tested by Microsoft.
However it breaks incapsulation and maybe ISP from SOLID. Because we can cast IWindowsService to WindowsService or even to ServiceController.
What is the best way to deal with standart stable types?
Please refer me to another question if we have.
Thanks in advance.
interface ISomeInterface
{
void Configure();
}
class SomeType : ISomeInterface
{
public void Configure()
{
var windowsService = new ServiceController("msdtc");
windowsService.Start();
}
}
I would do it like above. Now nothing should directly depend on SomeType. Everything should depend on ISomeInterface. That keeps the dependency on ServiceController limited to a single class.
The new operator really isn't a problem. There's no IServiceController that ServiceController implements, so if you want to use it, you have to tie yourself to it. By hiding it in SomeType which does implement an interface, at least you've limited how many things have a direct dependency on it.
The problem you are dealing with is a subtype of a larger problem, the issue of dealing with system level calls in IoC.
Another example of the problem is the use of DateTime.Now. If you call this in your code, there is no way to isolate it away, which is a problem if you want to test in various time scenarios.
One solution is to abstractify away all system level calls, so that you can substitute your own mock operating system for the purpose of testing. Here is an example for DateTime. I'll provide an example for your specific issue too:
interface IOperatingSystem
{
void StartService(string name);
}
class OperatingSystem : IOperatingSystem
{
public virtual void StartService(string name) {
var windowsService = new ServiceController(name);
windowsService.Start();
}
}
class SomeType : ISomeType
{
private readonly IOperatingSystem _operatingSystem;
public SomeType(IOperatingSystem operatingSystem)
{
_operatingSystem = operatingSystem;
}
public void Configure()
{
_operatingSystem.StartService("msdtc");
}
}
In your IoC container:
container.RegisterType<IOperatingSystem, OperatingSystem>();
container.RegisterType<ISomeType, SomeType>();
Now you can isolate away all you want, just by overriding your operating system class:
class MockOperatingSystem : OperatingSystem
{
public override StartService(string name)
{
//Do something worthy of testing, e.g. return normally or throw an exception
}
}
and register (in your unit tests) like this:
container.RegisterType<IOperatingSystem, MockOperatingSystem>();
Now when you go to code this, you might choose to have different interfaces for different system functions (e.g. maybe you want a IServiceControlManager that is separate from other O/S calls). That is fine, and common. I prefer one big class for all my O/S calls, because I know those O/S calls are not going to change. Well, they might change, but if they do, I have much bigger problems, and rework will be unavoidable anyway.
Background / Goal
We have several "client sites" on our web app that users can switch between
We do a lot of wiring up of objects based on factories that take in the client site ID and create an instance
I would like to inject these dependencies into the classes instead
I also want to make sure I can pass in my own implementations to the constructor for the purposes of unit testing.
We have initially elected to use StructureMap 3.x to do so, but are open to alternatives if they can help us solve this scenario gracefully.
Question
In instances where I require a different dependency based on a client site ID that I'll only get at run-time, what is the appropriate way to set up an IoC container and the appropriate way to request the object from it in order to make it as painless as possible?
Am I thinking about this wrong and unintentionally creating some sort of anti-pattern?
Example Code
Normally we're doing something like the following coming in:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = new dependentObjectFactory(clientSiteID).GetDependentObject();
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
What I'd like to do:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = MyTypeResolver.GetWIthClientContext<IDependentObject>(clientSiteID);
}
public MyService(int clientSiteID, IDependentObject dependentObject)
{
// ...
_dependentObject = dependentObject;
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
I would set up the IoC container in such a way that I can use my MyTypeResolver to pass in the clientSiteID, and have the container call my DependentObjectFactory and return the correct object result.
I'm new to IoC containers, and while I'm trying to plow through the literature, I have the feeling it may be easier than I'm making it so I'm asking here.
Probably the simplest way to do this is to use an Abstract Factory. Most IOC frameworks can auto-create them for you, but here's how you can do it manually (I always prefer to do it manually first so I know it works, and then you can check out how the framework can help you automagic it)
Now one thing to mention - I would recommend a slight readjustment of how the final solution works, but I'll go into that once I have shown how it can currently work. Example below assumes Ninject and please excuse any typos, etc.
First create an interface for your dependency
public interface IDependentObject
{
void DoSomething();
}
Then declare empty marker interfaces for each specific implementation of IDependentObject
public interface INormalDependentObject:IDependentObject{};
public interface ISpecialDependentObject:IDependentObject{}
and implement them:
public class NormalDependentObject:INormalDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something}
}
public class DependentObject:ISpecialDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something really special}
}
and of course as you mentioned you may have many more implementations of IDependentObject.
There may be a more elegant way of allowing your IOC framework to resolve at runtime without having to declare the marker interfaces; but for now I find it useful to use them as it makes the binding declarations easy to read :)
Next, declare an interface and implementation of an IDependentObjectFactory:
public interface IDependentObjectFactory
{
IDependentObject GetDependenObject(int clientID);
}
public class DependentObjectFactory: IDependentObjectFactory
{
readonly _kernel kernel;
public DependentObjectFactory(IKernel kernel)
{
_kernel=kernel;
}
public IDependentObject GetDependenObject(int clientID)
{
//use whatever logic here to decide what specific IDependentObject you need to use.
if (clientID==100)
{
return _kernel.Get<ISpecialDependantObject>(
new ConstructorArgument("clientID", clientID));
}
else
{
return _kernel.Get<INormalDependentObject>(
new ConstructorArgument("clientID", clientID));
}
}
}
Wire these up in your Composition Root:
_kernel.Bind<INormalDependentObject>().To<NormalDependentObject>();
_kernel.Bind<ISpecialDependentObject>().To<SpecialDependentObject>();
_kernel.Bind<IDependentObjectFactory>().To<DependentObjectFactory>();
and finally inject your factory into the service class:
public class MyService
{
IDependentObject _dependentObject;
readonly IDependentObjectFactory _factory;
//in general, when using DI, you should only have a single constructor on your injectable classes. Otherwise, you are at the mercy of the framework as to which signature it will pick if there is ever any ambiguity; most all of the common frameworks will make different decisions!
public MyService(IDependentObjectFactory factory)
{
_factory=factory;
}
public void DoAThing(int clientID)
{
var dependent _factory.GetDependentObject(clientID);
dependent.DoSomething();
}
}
Suggested changes
One immediate change from your structure above is that I have left clientID out of the service constructor and moved it to a method argument of DoAThing; this is because it makes a bit more sense to me that the Service itself would be stateless; of course depending on your scenario, you may want to not do that.
I mentioned that I had a slight adjustment to suggest , and it's this; the solution above depends (no pun!) on implementations of IDependentObject having a constructor with this signature:
public SomeDependency(int clientID)
If they don't have that signature then the factory won't work; personally I don't like my DI to have to know anything about constructor params because it takes you out of purely dealing with interfaces and forcing you to implement specific ctor signatures on your concrete classes.
It also means that you can't reliably make your IDependentObjects be part of the whole DI process (i.e whereby they themselves have dependency graphs that you want the framework to resolve) because of the forced ctor signature.
For that reason I'd recommend that IDependentObject.DoSomething() itself be changed to DoSomething(int clientID) so that you can elide the new ConstructorArgument part of the factory code; this means that your IDependentObject s can now all have totally different ctor signatures, meaning they can have different dependencies if needs be. Of course this is just my opinion, and you will know what works best in your specific scenario.
Hope that helps.
Hi how do we implement interface in a real time scenario??
This is my situation
I have made an interface IPayPal which has 2 methods
void SaleTransaction();
void VoidTransaction();
now i have a class PayPal which implements this service.
class PayPal:IPayPal{
public void SaleTransaction(){
// Implementation happens here
}
public void VoidTransaction(){
// Implementation happens here
}
}
now i have a service that requests the services from PayPal
lets say
class Service{
IPayPal pp=null;
static void Main(){
pp=new PayPal();
//Now i do not want to expose all the methods in my class PayPal
// is there any other way to just show pp.SaleOneTransaction() method?? i donot want the //PayPal class to be present in this Program..
//Please tell me how to acheive this.
}
}
i.e Please tell me a way in which i can initialise my interface class without revealing the class that implements the interface.
Thanks
I would suggest:
read about dependency injection and how it can help you resolve dependencies easily and in a loose coupled way.
the interface name "IPayPal" is not very good name IMHO. It is very specific to one payment provider. Suppose tomorrow you want to implement another payment method that is not paypal, yet you want to use the same interface. I think the name should be generic like "IPaymentProvider", and the current implementation is PayPal (but no other class using that interface should care or know about this).
good luck!
Two options:
Don't expose public methods you don't want to be called from other assemblies, pretty simply. Don't expose even internal methods you don't want to be called from other classes in the assembly.
Create a wrapper which proxies all calls:
public class PaymentProxy : IPayPal
{
private readonly IPayPal original;
public PaymentProxy(IPayPal original)
{
this.original = original;
}
public void SaleTransaction()
{
original.SaleTransaction();
}
public void VoidTransaction()
{
original.VoidTransaction();
}
}
At this point, you can create a PaymentProxy with your original "secret" object, trust that not to leak the information about it, and hand the proxy to anything. Of course, this isn't secure against reflection etc - but it does hide the prevent the implementation details from being "accidentally" used in a quick and dirty, "Well I know it'll really be a PayPal, so let's just cast to that..." hack.
You can separate 2 methods into 2 interfaces.
interface IPayPal1{
void SaleTransaction();
}
interface IPayPal2{
void VoidTransaction();
}
class PayPal:IPayPal1, IPayPal2{
void SaleTransaction(){
//
}
void VoidTransaction(){
//
}
}
class Service{
IPayPal1 pp=null;
static void Main(){
pp=new PayPal(); //you cannot access VoidTransaction here
}
}
I am making a payment system for my site. Users can select one of several payment providers to pay, but all should behave in the same way. I thought to represent this behavior like this:
public abstract class PaymentProvider {
private static var methods = Dictionary<String,PaymentProvider>
{
{"paypal",new PaymentProviderPaypal()},
{"worldpay",new PaymentProviderWorldpay()}
}
public static Dictionary<String,PaymentProvider> AllPaymentProviders
{
get {return methods;}
}
public abstract pay();
}
public class PaymentProviderPaypal : PaymentProvider {
public override pay() {
}
}
public class PaymentProviderWorldpay : PaymentProvider {
public override pay() {
}
}
You are supposed to use this by writing PaymentProvider.AllPaymentProviders["key"].pay(). The idea is that the functions using this class don't need to know about how the underlying payment provider is implemented, they just need to know the key.
However, at the moment, if you have access to the PaymentProvider class, you also have access to the inheriting classes. Its possible to instantiate a new copy of the inheriting classes, and make use of them in an unexpected way. I want to encapsulate the inheriting classes so that only the abstract PaymentProvider knows about them.
How should I do this? Different protection levels like protected don't work here - In Java, protected means that only other classes in the namespace can use that class, but in C# it means something else.
Do I have the right idea here? Or should I use a different method?
A couple of options spring to mind:
Put this in a separate assembly from the client code, and make the implementations abstract
Put the implementations inside the PaymentProvider class as private nested classes. You can still separate the source code by making PaymentProvider a partial class - use one source file per implementation
The first option is likely to be the cleanest if you don't mind separating the clients from the implementation in terms of assemblies.
Note that both of these are still valid options after the change proposed by Jamiec's answer - the "visibility" part is somewhat orthogonal to the inheritance part.
(As an aside, I hope the method is really called Pay() rather than pay() :)
Your inheritance heirachy is a bit wonky, I would be tempted to do it a similar but crucially different way.
public interface IPaymentProvider
{
void Pay()
}
// Implementations of IPaymentProvider for PaypalPaymentProvider & WorldpayPaymentProvider
public static class PaymentHelper
{
private static var providers = Dictionary<String,IPaymentProvider>
{
{"paypal",new PaymentProviderPaypal()},
{"worldpay",new PaymentProviderWorldpay()}
}
public static void Pay(string provider)
{
if(!providers.Containskey(provider))
throw new InvalidOperationException("Invalid provider: " + provider);
providers[provider].Pay();
}
}
Then the usage would be something like PaymentHelper.Pay("paypal").
Obviously if there is more data to provide to the Pay method this can be added to both the interface, and the helper. for example:
public interface IPaymentProvider
{
void Pay(double amount);
}
public static void Pay(string provider, double amount)
{
if(!providers.Containskey(provider))
throw new InvalidOperationException("Invalid provider: " + provider);
providers[provider].Pay(amount);
}
I'll explain my problem with an example.
I have an AnimalService, allowing me to increase the amount of show time the favourite animal gets for a specific zoo:
public sealed class AnimalService<TZoo> : IAnimalService<TZoo> where TZoo : IZoo
{
private readonly IFavouriteAnimalResolver<TZoo> favouriteAnimalResolver;
private readonly IAnimalShowTimeService animalShowTimeService;
public AnimalService(
IFavouriteAnimalResolver<TZoo> favouriteAnimalResolver,
IAnimalShowTimeService animalShowTimeService)
{
this.favouriteAnimalResolver = favouriteAnimalResolver;
this.animalShowTimeService = animalShowTimeService;
}
public void IncreaseShowTimeForFavouriteAnimal(TZoo zoo)
{
var favouriteAnimal = favouriteAnimalResolver.GetFavouriteAnimal(zoo);
animalShowTimeService.IncreaseShowTimeForAnimal(favouriteAnimal);
}
}
The AnimalService uses a resolver to get the favourite animal for TZoo, and then it calls an instance of IAnimalShowTimeService to increase the amount of show time the favourite animal will get. Below is the definition of the IFavouriteAnimalResolver interface and implementation of it that allows me to resolve the favourite animal for LondonZoo:
public interface IFavouriteAnimalResolver<TZoo> where TZoo : IZoo
{
IAnimal GetFavouriteAnimal(TZoo londonZoo);
}
public class LondonZooFavouriteAnimalResolver : IFavouriteAnimalResolver<LondonZoo>
{
public IAnimal GetFavouriteAnimal(LondonZoo londonZoo)
{
return new Lion();
}
}
Oki, so all good so far. Now for the complication. I would like to perform some animal specific logic once the IncreaseShowTimeForFavouriteAnimal is run. So my base AnimalShowTimeService stub looks like this:
public class AnimalShowTimeService : IAnimalShowTimeService
{
public void IncreaseShowTimeForAnimal(IAnimal animal)
{
// Update the show time for the animal
// Now call out to the AnimalUpdatedService<> instance to do any logic required for the animal
}
}
I would like to be able to call an update service that will get resolved via structuremap for the specific animal type, so I can run some update logic related to that specific type of animal. I have the following animalupdated interfaces for this purpose:
public interface IAnimalUpdatedService<T> where T : IAnimal
{
void LogTheUpdate(T animal);
}
public class DefaultAnimalUpdatedService<T> : IAnimalUpdatedService, IAnimalUpdatedService<T> where T : IAnimal
{
public void LogTheUpdate(T animal)
{
}
}
public class LionUpdatedService : IAnimalUpdatedService<Lion>
{
public void LogTheUpdate(Lion animal)
{
Console.WriteLine("The lion was updated");
}
}
As you can see, I have a DefaultAnimalUpdatedService which I want to be used when no specific update service was registered for an animal. I also have a LionUpdatedService which I would like to use every time a Lion's show time was increased for a zoo.
My problem is that because the favourite animal for a zoo can be any animal, the IFavouriteAnimalResolver returns an IAnimal type back and not a concrete. So I am not sure how I can use structuremap within IncreaseShowTimeForAnimal to get the LionUpdatedService service when a Lion's show time has been updated. I have played around with following code, but this won't work because I don't know the concrete at design time:
public class AnimalShowTimeService : IAnimalShowTimeService
{
public void IncreaseShowTimeForAnimal(IAnimal animal)
{
// Update the show time for the animal
var animalUpdatedService = ObjectFactory.ForGenericType(typeof(IAnimalUpdatedService<>))
.WithParameters(animal.GetType())
.GetInstanceAs<IDONTKNOWTHECONCRETE>();
animalUpdatedService.LogTheUpdate(animal);
}
}
I hope this all is clear. :)
I am not very well versed in StrutureMap, so would appreciate if anyone knows of an elegant way to approach this problem.
I have zipped up a test project I created using the above described code. You can download it here if you want to have a quick environment to fool around in:
[removed this link - no longer needed]
EDIT:
This is just a test project I created to illustrate the problem I am currently having in a much larger and more complex project. Unfortunately I can't redesign the entire architecture of the project to find a better design more geared towards this solution as I simply don't have the time. Being able to get the structuremap call simply return the correct concrete based on requirements above would be my immediate win. Learning about a better design to ensure things like this don't happen to me again would be a secondary win.
Thanks people :)
A few points:
a) Following the principle of "Tell, don't ask", it is not the AnimalShowTimeService's reposibility to resolve the type. Push the Animal to another object to make the choice.
b) Hardcoding references to ObjectFactory inside your domain is a bad design. The purpose of a DI container is to decouple your objects, not move the coupling somewhere else (StructureMap in this case).
Edit:
With regards to a) don't solve it in a polymorphic manner. You don't need generics to share behaviour, and inheritance hierachies only increase coupling. If you really do need to go down this path, I think implementing your own Convention might be what you're looking for. Or you could name every instance of IAmimal, and resolve the service with ObjectFactory.GetInstance(animal.GetType().ToString()), but that is clearly not ideal.
I think the point is however, that you're doing this as an exercise for DI & DI containers (I think), and if you can't get your design to fit, maybe you need to scrap it and start again, rather than trying to force a square peg into a round hole.
Oki, I have got a solution for my problem. Namely, the Visitor pattern. :-)
Quick reference: The Visitor Pattern
So I define a show time updated visitor, which can contain logic for each specific animal type:
public interface IShowTimeUpdatedVisitor
{
void Visit(Lion lion);
void Visit(Elephant lion);
void Visit(IAnimal animal);
}
public class ShowTimeUpdatedVisitor : IShowTimeUpdatedVisitor
{
public void Visit(Lion lion)
{
//do stuff with a lion
}
public void Visit(Elephant elephant)
{
//do stuff with an elephant
}
public void Visit(IAnimal animal)
{
// this will be the default which will be hit if no Visit method for the concrete exists
}
}
Then I have made modifications to the IAnimal interface to allow each implementation to call the correct method against ShowTimeUpdatedVisitor:
public interface IAnimal
{
void ShowTimeUpdated(IShowTimeUpdatedVisitor updatedVisitor);
}
public class Lion : IAnimal
{
public void ShowTimeUpdated(IShowTimeUpdatedVisitor updatedVisitor)
{
updatedVisitor.Visit(this);
}
}
Now, I can implement my AnimalShowTime service like this:
public class AnimalShowTimeService : IAnimalShowTimeService
{
readonly IShowTimeUpdatedVisitor showTimeUpdatedVisitor;
public AnimalShowTimeService(
IShowTimeUpdatedVisitor showTimeUpdatedVisitor)
{
this.showTimeUpdatedVisitor = showTimeUpdatedVisitor;
}
public void IncreaseShowTimeForAnimal(IAnimal animal)
{
animal.ShowTimeUpdated(showTimeUpdatedVisitor);
}
}
So in the end I didn't have to do any messy StructureMap code. :)
Hope this helps someone else.