Dependency injection with interfaces or classes - c#

I've been guilty of having a 1-to-1 relationship between my interfaces and concrete classes when using dependency injection. When I need to add a method to an interface, I end up breaking all the classes that implement the interface.
This is a simple example, but let's assume that I need to inject an ILogger into one of my classes.
public interface ILogger
{
void Info(string message);
}
public class Logger : ILogger
{
public void Info(string message) { }
}
Having a 1-to-1 relationship like this feels like a code smell. Since I only have a single implementation, are there any potentially issues if I create a class and mark the Info method as virtual to override in my tests instead of having to create an interface just for a single class?
public class Logger
{
public virtual void Info(string message)
{
// Log to file
}
}
If I needed another implementation, I can override the Info method:
public class SqlLogger : Logger
{
public override void Info(string message)
{
// Log to SQL
}
}
If each of these classes have specific properties or methods that would create a leaky abstraction, I could extract out a base class:
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
}
The reason why I didn't mark the base class as abstract is because if I ever wanted to add another method, I wouldn't break existing implementations. For example, if my FileLogger needed a Debug method, I can update the base class Logger without breaking the existing SqlLogger.
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
public virtual void Debug(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
public override void Debug(string message) { }
}
Again, this is a simple example, but when I should I prefer an interface?

The "Quick" Answer
I would stick with interfaces. They are designed to be contracts for consumption for external entities.
#JakubKonecki mentioned multiple inheritance. I think this is the biggest reason to stick with interfaces as it will become very apparent on the consumer side if you force them to take a base class... no one likes base classes being thrust upon them.
The Updated "Quick" Answer
You have stated issues with interface implementations outside your control. A good approach is to simply create a new interface inheriting from the old one and fix your own implementation. You can then notify the other teams that a new interface is available. Over time, you can deprecate older interfaces.
Don't forget you can use the support of explicit interface implementations to help maintain a nice divide between interfaces that are logically the same, but of different versions.
If you want all this to fit in with DI, then try not to define new interfaces and instead favour additions. Alternatively to limit client code changes, try to inherit new interfaces from old ones.
Implementation vs. Consumption
There is a difference between implementing the interface and consuming it. Adding a method breaks the implementation(s), but does not break the consumer.
Removing a method obviously breaks the consumer, but does not break the implementation - however you wouldn't do this if you are backwards-compatibility conscious for your consumers.
My Experiences
We frequently have a 1-to-1 relationship with interfaces. It is largely a formality but you occasionally get nice instances where interfaces are useful because we stub / mock test implementations, or we actually provide client-specific implementations. The fact that this frequently breaks that one implementation if we happen to change the interface isn't a code smell, in my opinion, it is simply how you work against interfaces.
Our interface-based approach is now standing us in good stead as we utilise techniques such as the factory pattern and elements of DI to improve an aged legacy code base. Testing was able to quickly take advantage of the fact that interfaces existed in the code base for many years before finding a "definitive" use (ie, not just 1-1 mappings with concrete classes).
Base Class Cons
Base classes are for sharing implementation details to common entities, the fact they are able to do something similar with sharing an API publicly is a by-product in my opinion. Interfaces are designed to share API publicly, so use them.
With base classes you could also potentially get leakage of implementation details, for example if you need to make something public for another part of the implementation to use. These are no conducive to maintaining a clean public API.
Breaking / Supporting Implementations
If you go down the interface route you may run into difficulty changing even the interface due to breaking contracts. Also, as you mention, you could break implementations outside of your control. There are two ways to tackle this problem:
State that you won't break consumers, but you won't support implementations.
State that once an interface is published, it is never changed.
I have witnessed the latter, I see it come in two guises:
Completely separate interfaces for any new stuff: MyInterfaceV1, MyInterfaceV2.
Interface inheritance: MyInterfaceV2 : MyInterfaceV1.
I personally wouldn't choose to go down this route, I would choose to not support implementations from breaking changes. But sometimes we don't have this choice.
Some Code
public interface IGetNames
{
List<string> GetNames();
}
// One option is to redefine the entire interface and use
// explicit interface implementations in your concrete classes.
public interface IGetMoreNames
{
List<string> GetNames();
List<string> GetMoreNames();
}
// Another option is to inherit.
public interface IGetMoreNames : IGetNames
{
List<string> GetMoreNames();
}
// A final option is to only define new stuff.
public interface IGetMoreNames
{
List<string> GetMoreNames();
}

Your ILogger interface is breaking the interface segregation principle when you start adding Debug, Error, and Critical methods besides Info. Take a look at the horrible Log4Net ILog interface and you'll know what I'm talking about.
Instead of creating a method per log severity, create a single method that takes a log object:
void Log(LogEntry entry);
This completely solves all of your problems, because:
LogEntry will be a simple DTO and you can add new properties to it, without breaking any client.
You can create a set of extension methods for your ILogger interface that map to that single Log method.
Here's an example of such extension method:
public static class LoggerExtensions
{
public static void Debug(this ILogger logger, string message)
{
logger.Log(new LogEntry(message)
{
Severity = LoggingSeverity.Debug,
});
}
public static void Info(this ILogger logger, string message)
{
logger.Log(new LogEntry(message)
{
Severity = LoggingSeverity.Information,
});
}
}
For a more detailed discussion on this design, please read this.

You should always prefer the interface.
Yes, in some cases you will have the same methods on class and interface, but in more complex scenarios you won't. Also remember, that there is no multiple inheritance in .NET.
You should keep your interfaces in a separate assembly and your classes should be internal.
Another benefit of coding against interfaces is an ability to easily mock them in unit tests.

I Prefer interfaces. Given stubs and mocks are also implementations (sort of), I always have at least two implementations of any interface. Also, Interfaces can be stubbed and mocked for tests.
Further, the contract angle that Adam Houldsworth mentions is very constructive. IMHO it makes the code cleaner than 1-1 implementations of interfaces make it smelly.

Related

Implement Interface Segregation Principle for .NET Framework interfaces

I am implementing IServiceLocator(CommonServiceLocator package) into my custom ServiceLocator class.
The interface has the following methods to implement:
public class CustomServiceLocator : IServiceLocator
{
private IServiceProvider _provider;
public RatioDissectionServiceLocator(IServiceProvider provider)
{
_provider = provider;
}
public IEnumerable<object> GetAllInstances(Type serviceType)
{
throw new NotImplementedException();
}
public IEnumerable<TService> GetAllInstances<TService>()
{
throw new NotImplementedException();
}
public object GetInstance(Type serviceType)
{
throw new NotImplementedException();
}
public object GetInstance(Type serviceType, string key)
{
throw new NotImplementedException();
}
public TService GetInstance<TService>()
{
return _provider.GetService<TService>();
}
}
I don't want to implement all the methods in my class. How can we achieve ISP for inbuilt C# interfaces?
Any help?
The Interface Segregation Principle states:
No client should be forced to depend on methods it does not use.
What this means is that despite many unclear and misleading explanations of the principle, a big interface by itself doesn't violate the principle. Perhaps another class actually does depend on all the members of the interface. So we wouldn't look at an interface like IServiceLocator and try to "fix" it somehow.
The ISP is from the point of view of classes that depend on interfaces. If an interface has 20 members and my class depends on all of them, it's not an ISP violation. (It's likely all sorts of other bad things that have nothing to do with the ISP.) If another class depends on the exact same interface and uses only a few members, that's an ISP violation.
In both examples it's the same interface. The principle isn't about the interface. It's about whether or not a class that depends on the interface uses all of its members.
(Another weird example I see a lot is a big interface and a class that implements the interface but throws NotImplementedException for some members. That's also bad, and it's a Liskov Substitution violation, but it has nothing at all to do with ISP. Implementing an interface is not depending on it.)
One way to avoid ISP violations is to write interfaces from the perspective of classes that depend on them. Whatever your class needs from its dependency, write your interface to describe exactly that. If the concrete inner implementation is a framework class with 100 members, wrap it in your own class:
public interface ISmallSegregatedInterface
{
void DoJustWhatMyClassNeeds();
}
public class TheImplementation : ISmallSegregatedInterface
{
private readonly FrameworkClassWithLotsOfMembers _inner;
public TheImplementation(FrameworkClassWithLotsOfMembers inner)
{
_inner = inner;
}
public void DoJustWhatMyClassNeeds()
{
_inner.CallSomeMethod();
}
}
Now the class that needs to depend on one method can depend on an interface with just that one method. (Over time I've found that this leads to lots of single-method interfaces. I think that logically leads to depending on functions and delegates but a single-method interface is okay.
That is interface segregation. Your classes don't depend on a big interface they don't need. They depend on one ore more interfaces that describe exactly what they need. This is often accomplished by creating the interface from the perspective of the class that needs to depend on it.
What you might find is that no class needs to depend on all of the methods of IServiceLocator.
Maybe all you need is this:
TService GetInstance<TService>();
But does a class really need to depend on a method that can return anything? In other words, you're probably only going to request one or two dependencies. So maybe what you really need is this:
public interface ISomethingSpecificFactory
{
ISomethingSpecific CreateInstance();
}
Or you might find that you don't need the factory at all - perhaps you can just inject ISomethingSpecific instead of a factory that creates an instance of ISomethingSpecific.
Another way of looking at it: If you don't need to implement all of the methods of IServiceLocator then you don't need to create a class that implements IServiceLocator.
IServiceLocator is a framework interface. Unlike most software we create, it doesn't exist to meet a narrow, specific need. It meets a broader variety of needs that are determined as we write our software. That's why it makes more sense that it has all sorts of varied methods we might not need.
One reason for the ISP is that if lots of classes depend on different members of an interface, we might be pressured to change the interface because of the needs of one client, and those changes affect other clients that depend on other methods, in effect coupling them all together.
We can't change IServiceLocator so that pressure doesn't exist. So technically, even if we did violate the ISP by depending on that interface, it wouldn't have the harmful effect that the ISP protects us from.

Prevent implementation of method that is not an interface method

Is it possible to prevent implementation of public non interface methods in a class that implements an interface?
E.g.
public interface ICanDoSomething
{
void CanDoA();
void CanDoB();
}
public class Doer : ICanDoSomething
{
public void CanDoA()
{
//Do A
}
public void CanDoB()
{
//Do B
}
public void CanDoC()
{
//Don't do this!!! it's not defined in the interface!!!
}
}
Just to clarify, I would like to prevent it at compilation time, not at run time.
If C# would be able to do what you want to achieve, the language itself would destroy one of object-oriented programming features: encapsulation.
Let implementers implement your interfaces their own way and focus on quality of interface implementations rather than putting your effort on don't implement more methods than ones defined by the interface (i.e. implement an unit/integration test that implementers should pass to certify that black boxes actually work as you expect).
When you use interfaces you get black boxes: you don't care about how an implementation does the job, but you care about if it does the job right.
Taken from some comment you added in your own question:
No specific use case, just want to direct those who use libraries to
component oriented functionality and avoid god objects.
You want to avoid god objects but you want god methods. Everyone will always prefer a class which has a good separation of concerns and segmentation rather than see 3 methods with 1k code lines each one.
OP said...
What about breaking the single responsibility principle? If a class
implementing an interface suddenly starts doing stuff which can easily
be a responsibility of other class, isn't it breaking OOP as well?
No, single responsibility principle isn't tied to the definition of object-oriented programming (i.e. inheritance, polymorphism and encapsulation) but it's about code quality.
Code quality can't be ensured with interfaces nor using any own programming language construct. This is the mission of code review.
Of course, automated testing ensures that code will run with quality, which is different than coded with quality.
Technically, you can't prevent CanDoC() declaration, but you can do it useless via factory method and internal implementation:
// interface is public when its implementation is internal
internal class Doer : ICanDoSomething {
// To prevent creating Doer as Doer
protected internal Doer() { // or internal
//Some staff if required
}
public void CanDoA() {... }
public void CanDoB() {... }
// Technically possible
public void CanDoC() {... }
}
public static class DoerFactory {
// ... create instead Doer as ICanDoSomething instance
// (factory method)
public static ICanDoSomething Create() {
return new Doer();
}
}
...
ICanDoSomething test = DoerFactory.Create();
test.CanDoA(); // OK
test.CanDoC(); // Compile time error
(test as Doer).CanDoC(); // Compile time error when called in an assembly other than Doer

What is the best way to create Interfaces that are injected into constructor in C#? [closed]

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 7 years ago.
Improve this question
I'm working in a project where external data is fetched from different sources such as database, 3 external web apis, web config.
To avoid tight coupling some interfaces are used and passed in my classes constructors, such as:
public Dog(IDataAccess dataAccess, IConverter converter, IConfigAccess configAccess,
ITimezoneAccess timezoneAccess)
public Cat(IDataAccess dataAccess, IConverter converter, IConfigAccess configAccess,
ITimezoneAccess timezoneAccess)
public Duck(IDataAccess dataAccess, IConverter converter, IConfigAccess configAccess,
ITimezoneAccess timezoneAccess)
It helps us in unit tests because we create mock implementations of these interfaces.
When developing the code, there are some common functions between all classes such as Datetime operations, Fixed values methods, etc. I decided to create some static classes to divide this functionality into specific classes such as DatetimeHelper, FixedCalculationsHelper, StringHandlingHelper, etc.
I got the suggestion to avoid using these static classes and convert them into strategies with interfaces and pass them in the constructor as the other external data access interfaces.
When I apply this, the constructor of my classes will have a lot of Interface parameters, such as:
public Dog(IDataAccess dataAccess, IConverter converter, IConfigAccess configAccess,
ITimezoneAccess timezoneAccess, IStringHandling stringHandler,
IDatetimeHelper datetimeHelper ...etc...
What is the most elegant/best way to handle with this scenario?
(Not sure if some techniques are used here such as a container or something similar)
Why is it better to convert this static classes into interface/implementation strategies (even if this methods are static such as CalculateArea(int value1, int value2))?
Any comment or explanation is very welcome. Thanks in advance.
The purpose of using an Interface is that you are coding to abstractions and not concretions which removes the dependencies.
It's ok to pass many interfaces into the contructor, however you don't want to pass in concrete classes. You could use setter injection instead of constructor injection if you just don't want the contructor to have parameters.
public class Duck
{
IDataAccess DataAccess { get; set; }
IConverter Converter { get; set; }
IConfigAccess ConfigAccess { get; set; }
ITimezoneAccess TimezoneAccess { get; set; }
public Duck()
{
// parameterless contructor
}
}
Changing the implementations will be much easier by using Interfaces. It gives you greater control over the structure of the program. You want to have your classes open to extension but closed to modification, which is the Open Closed Principle. In my opinion I would make the helpers extension methods and forego making interfaces for them.
We apply Dependency Injection to allow code to be loosely coupled. Loosely coupled code makes our code very flexible. It allows our code to be tested in isolation, allows code to be deployed independently, allows us to intercept or decorate classes without having to make sweeping changes throughout the application.
But you don't need these characteristics for every dependency a class takes. For simple helper methods, that don't have any dependencies on their own, that never have to be replaced, decorated or intercepted, and don't complicate testing, there is little need to promote them to full components and hide them behind an abstraction. You will soon see that you want to test the consuming class in isolation, but with the real helper logic. And now you will have trouble wiring this all up in your unit test.
My advice is to not overdo it.
Having said that, even when you don't inject those simple helper methods, your classes might still have big constructors. Having constructors with many dependencies is a code smell. It is an indication that such class violates the Single Responsibility Principle (SRP), which means that a class has too many responsibilities. SRP violations lead to code that is hard to maintain and hard to test.
Fixing SRP violations is not always easy, but there are several patterns and practices that can help you to improve the design.
Refactoring to Aggregate Services is one of these practices. If a class has many dependencies, it is often possible to extra part of the logic of that class with those dependencies and place them behind a new abstraction: your aggregate service. That aggregate service does not expose its dependencies, but just exposes a method that allows access to that extracted logic.
A good indication of being able to apply this refactoring is if you have a group of dependencies that gets injected into multiple services. In your case you have a clear group consisting of IDataAccess, IConverter, IConfigAccess and ITimeZoneAccess. You might be able move two, three, or perhaps even all four to an aggregate service.
Letting cross-cutting concerns get tangled up with business logic is another common reason why classes get too big, with way too many dependencies. You will often see that transaction handling, logging, audit trailing, security checks, etc, get mixed up with business logic and gets duplicated throughout the code base.
An effective way around this is by moving these cross-cutting concerns out of the class that contains the business logic and apply it using interception or decoration. This works best if you have a SOLID design. Take a look at this article for instance to get an idea how to apply cross-cutting concerns without having to make sweeping changes throughout your code base.
Use StructureMap IoC container in your project. Have the constructor take those interfaces in, and make a registry in the project that sets up which class to use for each interface.
E.g.
public class DuckProjectRegistry : Registry
{
public DuckProjectRegistry()
{
For<IDataAccess >().Use<ConcreteClassDataAccess>();
For<IConverter>().Use<ConcreteConverterXYZ>();
For<IConfigAccess>().Use<ConcreteConfigAccess>().Singleton();
// etc.
}
}
public class Duck
{
private readonly IDataAccess _dataAccess;
private readonly IConverter _converter;
private readonly IConfigAccess _configAccess;
// etc.
public Duck(
IDataAccess dataAccess,
IConverter converter,
IConfigAccess configAccess
// ,etc.)
{
_dataAccess = dataAccess;
_converter = converter;
_configAccess = configAccess;
// etc.
}
If you don't want any DI container, for helpers, I advice you to utilize what I use to call "Abstract Intefacing"
Create empty interfaces:
public interface IDateTimerHelper { }
public interface IFixedCalculationsHelper { }
And then implement in extension classes
public static class DateTimerHelperExtension
{
public static void HelpMeForDateTimering(this IDateTimerHelper dth/*, params*/)
{
//Help here;
}
public static void HelpMe(this IDateTimerHelper dth/*, params*/)
{
//Help here;
}
}
public static class FixedCalculationsHelperExtension
{
public static void HelpMeForFixedCalculations(this IFixedCalculationsHelper fch/*, params*/)
{
//implement here
}
public static void HelpMe(this IFixedCalculationsHelper fch/*, params*/)
{
//implement here
}
}
Finally use like this
public class Dog:IFixedCalculationsHelper,IDateTimerHelper
{
public Dog(/*other injections*/)
{
//Initialize
}
public void DoWork()
{
(this as IDateTimerHelper).HelpMe();
(this as IFixedCalculationsHelper).HelpMe();
this.HelpMeForDateTimering();
this.HelpMeForFixedCalculations();
}
}

Implicit interface based on class

I have a lot of classes in my business layer that have an interface which must always have the same methods and properties as the public methods and properties of my business class. This is a common scenario, as the interface is needed for dependency injection and mocking while unit testing.
It would be optimal if I could somehow define the interface as the same as the public methods and properties of a class. That way I don't have to copy paste method definitions from my implemented class to my interface all the time. I don't see any logical problem with this, but I know that it's not directly possible to do in C#.
Perhaps someone can come up with a reasonable way to accomplish this?
Here is an example. Here is an interface.
public interface IAccountBusiness
{
Guid GetAccountIdByDomain(string domain);
void CreateAccount(string accountType, string accountName);
}
Here is the implementation:
public class AccountBusiness : IAccountBusiness
{
public Guid GetAccountIdByDomain(string domain)
{
// Implementation
}
public void CreateAccount(string accountType, string accountName)
{
// Implementation
}
}
If I want to add a parameter more in CreateAccount, for example "Email", then I have to add it to both the interface and the business class. In this example it's a minor nuisance but in larger scale projects it's ... well ... still a minor nuisance, but it doesn't have to be.
Resharper's Change Signature refactoring allows you to do that easily:

Does MEF lend any value to the Singleton pattern?

I am working on an MEF project to discover usage and implementation techniques. My first phase of discovery is to implement a dynamically configurable and centralized data controller. One way to customize behavior is to inherit a class I provide that enforces a singularity rule. While the Singleton pattern is much maligned in it's use, I may have found an implementation that could validate, to some degree, the pattern's struggling existence.
The Situation
Suppose a data control module (DataController) imported by the Host is intended to supply a common conduit to databases on request by sibling modules. I only need one DataController and to be composed as a module, DataController must implement IDataController. Implementation of DataProvider as the base class is purely optional; however, derivation from DataProvider will require some additional handling.
The Observations
Gathering the facts:
A static class cannot implement or
extend abstract classes or
interfaces. This fact alone
eliminates the use of a static class
to ensure a singular existence of a
DataController.
A DataController implementing the
Singleton pattern would ensure a
singular existence per application
domain. There is no restriction on
the DataController; allowed to inherit the
required interface to be imported and
composed in the Host.
Given derivation of DataController, the
standard implementation for the
Singleton pattern may prove to be
challenging in same cases. The
proposed data library provides both
publicly accessible classes:
IDataController, and an abstract
DataProvider. To ensure a single
instance of the derived DataController,
the implementation will require some
deviation from the norm.
The Solution
At this point, the solution seems clear. Implementation of the Singleton pattern by the DataHandler base class. I am not naive enough to think that there are other ways I could do this. But here is my rough expectations on how to implement the pattern:
// DataLibrary referenced by Host
public interface IDataController
{
IDataController Start();
DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection;
}
public abstract class DataProvider
{
// singleton implementation
private static IDataController dcInstance;
protected static IDataController Instance
{
get{ return dcInstance; }
}
// ========================
abstract IDataController CreateController();
protected IDataController instanceController<TDataController>()
where TDataController : IDataController, new()
{
return new TDataController ();
}
}
// references DataLibrary
[Export(typeof(IDataController))]
public class DataController : DataProvider, IDataController
{
public IDataController Start()
{
return CreateController();
}
protected override IDataController CreateController()
{
return instanceController<DataController>();
}
public SqlConnection CreateConnection(params string[] args)
{
// instance and return new SqlConnection
}
}
Keep in mind that I have been working this out - read, theorizing - and have not completed the implementation. There will most likely be some updates as I debug any issues.
Obviously, this implementation is only enforced if the DataController module inherits the abstract base class, DataProvider. Therefore, it stands to reason that we should enforce a rule of singularity to avoid abuse or misuse if the developer opts to derive a DataController from DataProvider.
All that said, I am curious if there is a more acceptable, or practical implementation than what I have devised. And, I begin to question if the Singleton pattern is the right choice. With the Singleton pattern's much maligned existence (and, for the most part, rightfully so), I should, therefore, question my choice.
Is there a more practical implementation to meet my requirements?
*Is this the right implementation of the Singleton pattern in this case?*
Does this implementation actually lend any value to the pattern's existence?
If you want to enforce the fact that only a single instance of a class exists in the container, then you can just set the "shared" part creation policy:
[Export(typeof(IDataController))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DataController : IDataController
{
...
}
Each part importing IDataController will then receive the same instance. Note that this already the default behavior in MEF if you specify no part creation policy at the import or export side.
You should not build "singletonness" into a class. Whether something is a singleton is part of the component metadata or the configuration of the container. Other dependency injection containers follow the same approach. For example, in autofac you declare something as being a singleton like this:
builder.Register(c => new DataController())
.As<IDataController>().SingleInstance();
Unless you have more implementation code that all derived classes from DataProvider would share, you might want to simply do away with your abstract class. This implementation guarantees thread-safey and uses lazy construction without the use of locks. However, requires .NET 4.
public interface IDataController
{
DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection;
}
[Export(typeof(IDataController))]
public class DataController : IDataController
{
// singleton implementation
private static volatile Lazy<IDataController> _ControllerInstance = new Lazy<IDataController>(() => new DataController());
public static IDataController ControllerInstance
{
get { return _ControllerInstance.Value; }
}
public DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection
{
throw new NotImplementedException();
}
}

Categories

Resources