Many programming languages have got a trait/mixin mechanism. You can find those in modern programming languages like Scala and Ruby. It is possible to make it work if language allows multiple inheritance (base class then can be treated like trait). But not in C#.
I tried to emulate somehow trait behaviour.
Steps - how it was done
Create project with ILoggingTrait in LoggingTrait namespace. ILoggingTrait interface
That will be used to annotate classes ("extending the trait") Extended class:
public class LoggableClass : ILoggingTrait
Define trait. Create another project and create class inside LoggingTrait namespace. Defined trait
It has to be public static class with public static methods that takes this ILoggable @this param.
It will be use as trait definition/placeholder. It can be used when implementing as a stub.
The project that uses the trait should reference project with ILoggingTrait, and that DummyLoggingTrait
Create project and class inside LoggingTrait namespace. This will be concrete implementation of the trait. Again it has to implement extension methods on ILoggingTrait.
Project that contains a class that uses the trait (Example) references two projects: the one that contains LoggingTrait.ILoggingTrait interface and one that contains concrete implementation.
This way, we can swap the implementations (just change reference in csproj to other project, or remove old reference and add new in Visual).
* We can mix methods into our classes.
* In case we have any method missing from our implementation we'll get a compile time error!
* Resolved at compile time (no real-time DI).
* Traits can also use state. Just specify the properties in an ITrait.
* No tools to pick concrete implementation easier, and no Intellisense with information that some methods from Dummy trait should be implemented.
* Changes of concrete trait implementation made project-wise.
Something Extra - interface with default implementation
Define interface -> Implement it using extension methods -> call from class if want to use default implementation using a convention:
this.MethodName(params, @default: true);
More about it in code (c'mon, it's just one file): [Here](https://github.com/lemmit/CSharpTraits/bl
Full code is available at Github.
I have also devoted a post about it here.