I have an Engine class, an App class that uses that Engine, and an interface IEngine that abstracts that:
public interface IEngine
{
void Foo();
}
public class Engine1 : IEngine
{
public void Foo()
{
//...
}
}
public class App1
{
public void Do()
{
IEngine1 e = new Engine1();
e.Foo();
}
}
Since I can have multiple Engines, I'm implementing an engine factory that produces engines and returns them as IEngine:
public class EngineFactory
{
public IEngine CreateEngine(string engineName)
{
//returns the right engine according to 'engineName'
}
}
That way an App and an Engine are loosely coupled, and any App class will not reference concrete Engines.
Finally, I want to be able to add new methods to (all of) my engines. The natural thing would be to add those methods to IEngine, but if I'll do that, I'll have to recompile all the Apps that use IEngine. My solution is to create a new interface IEngine2:
public interface IEngine2 : IEngine
{
void Goo();
}
But that will force me to change the CreateEngine method signature in my factory.
How can I avoid that? Should I change the factory to be generic? Should I use DI? Something else?
Edit: You can think about it this way- I'm responsible for the engines implementation, and my customers are implementing the Apps. Now there is a customer who needs a new capability from all of the engines, and I need to implement that capability without forcing all the other customers to recompile their apps (similar to an API implementation).
A solution could be to use the capability pattern :
public interface IEngine
{
bool TryGetCapability<T>(out T capability);
}
public interface ICapability1
{
void Foo();
}
public class Engine1 : IEngine, ICapability1
{
public bool TryGetCapability<T>(out T capability)
{
if (this is T)
{
capability = this as T;
return true;
}
capability = default(T);
return false;
}
public void Foo()
{
//...
}
}
public class App1
{
public void Do()
{
IEngine e = new Engine1();
ICapability1 cap1;
if (e.TryGetCapability(out cap1))
{
cap1.Foo();
}
}
}
I used the engine class to implement the capability but on a real app it will normally be implemented on one class per capability.
This is a common problem in the COM world, you should never modify a interface once it is published. The way COM usually works around this is using new version numbered interfaces that inherit from the previous version.
public interface IEngine
{
void Foo();
}
public interface IEngine2 : IEngine
{
void Goo();
}
public class EngineA : IEngine
{
public void Foo()
{
//...
}
}
public class EngineB : IEngine2
{
public void Foo()
{
//...
}
public void Goo()
{
//...
}
}
For your factory you can have it always return a IEngine or have it be generic and the user must specify the minimum interface the item has to support.
public class EngineFactory
{
public T CreateEngine<T>(string engineName) where T : IEngine
{
//returns the right engine according to 'engineName'
}
}
public class App
{
public void Do(EngineFactory factory)
{
//Creates a instance of EngineA
IEngine e = factory.CreateEngine<IEngine>("EngineA");
//returns a instance of EngineB
IEngine eB = factory.CreateEngine<IEngine>("EngineB");
//returns null
IEngine2 e2 = factory.CreateEngine<IEngine2>("EngineA");
//returns a instance of EngineB
IEngine2 e2B = factory.CreateEngine<IEngine2>("EngineB");
}
}
Related
I am writing a tranformer that takes some input and gives an output.I need to call a specific tranformer based on my input type.
public static myentrypoint( template t);
{
//I could do something like this.
switch(t)
{
case t1:
transformt1(..);
case t2:
transformt1(..);
....
}
}
Trasform1 : Itransform
{
tranform1(...);
}
Trasform2 : Itransform
{
tranform2(...);
}
I need to map which function to call based on what my template is. I can do a switch but are there more cleaner ways to do this using some design patterns ? I was thinking a of writing a static dictionary. I am new to OOP so any suggestions would be great.
If template is a class, and each template potentially has a different transform, then why not just include the transform function inside of your template class?
public static myentrypoint( ITemplate t);
{
t.transform();
}
The way that I do these types of situations is through the use of Generics. (Shameless self-promotion of a blog post)
Basically, you'll have your base class set up like this:
public abstract class Transformer<T>
where T : Template
{
public abstract void Transform(T item);
}
Then you derive for each of your types like this:
public class Transformer1 : Tansformer<Template1>
{
public void Transform(Template1 item)
{
}
}
public class Transformer2 : Transformer<Template2>
{
public void Transform(Template2 item)
{
}
}
Then you'll just need a factory to give you the correct Transformer.
public class TransformFactory
{
public Transformer<T> GetTransformer<T>(T item)
{
if (item is Template1)
return new Transformer1();
else if (item is Template2)
return new Transformer2();
// ...
}
}
The benefit of this approach is that you'll be able to encapsulate all behavior on that specific type in the concrete implementations. If there is any common behavior on them all, you can do that in the abstract base.
Invoking methods based on a parameter without switch-case statements in C#
In OOP, based on the [open/close principle] which says that software entities such as classes and functions should be open for extension, but closed
for modification.
Methods which use switch-case statement would call this principle into question. In order to implement this principle inside the codes without
causing changes in their functionality.
We use a pattern named "Delegate Dictionary Pattern".
For example, we have an entity named Template that keep input values as well as some of Transform classes for processing this Template.
Template class for keeping input value
public class Template
{
public int TransformNo { get; set; }
public string Title { get; set; }
}
ITransform interface for transform abstract
public interface ITransform
{
void Do(Template template);
}
Transform1 as a concrete class of ITransform
public class Transform1 : ITransform
{
public void Do(Template template)
{
Console.WriteLine($"Transform : {template.TransformNo}, TemplateTitle : { template.Title}");
}
}
Transform2 as a concrete class of ITransform
public class Transform2 : ITransform
{
public void Do(Template template)
{
Console.WriteLine($"Transform : {template.TransformNo}, TemplateTitle : { template.Title}");
}
}
TransformCordinator class for coordinating template of *ITransformer**
public class TransformCordinator
{
Dictionary<int, Action<Template>> transformMap = new Dictionary<int, Action<Template>>();
public TransformCordinator()
{
transformMap.Add(1, x => new Transform1().Do(x));
transformMap.Add(2, x => new Transform2().Do(x));
}
public void Do(Template template)
{
transformMap[template.TransformNo](template);
}
}
// example
class Program
{
static void Main(string[] args)
{
var transformCordinator = new TransformCordinator();
transformCordinator.Do(new Template() { TransformNo = 1, Title = "Hi!" });
Console.ReadLine();
}
}
I am looking on ways to improve the following code:
public interface IExample{ void Do(); }
public interface IExampleA: IExample {}
public class ExampleA: IExampleA { public void Do(); }
public interface IExampleB: IExample {}
public class ExampleB: IExampleB { public void Do(); }
public interface IExampleFactory{
IExample Make(TypesOfExamples thisIsAnEnum);
}
public class ExampleFactory: IExampleFactory {
IExampleA _exampleA;
IExampleB _exampleB;
public ExampleFactory(IExampleA exampleA, IExampleB exampleB)
{
_exampleA = exampleA;
_exampleB = exampleB;
}
public IExample Make(TypesOfExamples thisIsAnEnum)
{
switch(thisIsAnEnum)
{
case A: return _exampleA;
case B: return _exampleB;
}
}
}
Basically what I don't like is having to use the IExampleA and IExampleB, they are there only for being injected:
container.Bind<IExampleA>().To.<ExampleA>();
container.Bind<IExampleB>().To.<ExampleB>();
container.Bind<IExampleFactory>().To.<ExampleFactory>();
And it would be used like this
public class ExampleUsage()
{
ExampleFactory _exampleFactory;
public ExampleUsage(ExampleFactory exampleFactory)
{
_exampleFactory = exampleFactory;
}
public void useFactory(Test obj)
{
var implementation = _exampleFactory.Make(obj.ThisIsAnEnum);
implementation.Do();
}
}
Any pointers would be appreciated, thanks!
**Edit I had forgotten to mention that both ExampleA and ExampleB has some dependencies that need to be taken care of by the DI
public class ExampleA: IExampleA
{
IDependencyA _dependencyA;
IDependencyB _dependencyB;
public ExampleA(IDependencyA dependencyA, IDependencyB dependencyB)
{
_dependencyA = dependencyA;
_dependencyB = dependencyB;
}
public void Do();
}
public class ExampleB: IExampleB
{
IDependencyA _dependencyA;
IDependencyB _dependencyB;
IDependencyC _dependencyC;
public ExampleA(IDependencyA dependencyA, IDependencyB dependencyB, IDependencyC dependencyC)
{
_dependencyA = dependencyA;
_dependencyB = dependencyB;
_dependencyC = dependencyC;
}
public void Do();
}
container.Bind<IDependencyA>().To.<DependencyA>();
container.Bind<IDependencyB>().To.<DependencyB>();
container.Bind<IDependencyC>().To.<DependencyC>();
I think you are doing wrong with the Factory.
There is no point to inject ExampleA and ExampleB to the Factory.
Since the factory pattern is responsible for creation, therefore you can do instantiation from inside factory class.
This could be easy to replace the factory with the other implementations of the IExampleFactory.
*Edited added more details.
Actually the DI container can be considered as a factory (both are responsible for objects creation).
But if you want to go the factory way, you can implement you own instantiation logic.
Of course, you need to handle the dependencies by the factory.
The factory interface is better to define the objects to be created separately.
public interface IExampleFactory
{
IExampleA CreateExampleA();
IExampleB CreateExampleB();
}
Then the concrete factory should handle the instantiation process of each object.
you can do anything to get all dependencies to instantiate the object (each object can have different dependencies).
public class ExampleFactory: IExampleFactory
{
IExampleA CreateExampleA()
{
//instantiating concrete object A with its dependencies
return concreteA;
}
IExampleB CreateExampleB();
{
//instantiating concrete object B with its dependencies
return concreteB;
}
}
How can a variant of the Template Method pattern be implemented whereby the concrete class does not inherit from the base class, but the overall feature of the pattern is maintained. The reason it cannot inherit is that it's forced to inherit from another class and multiple-inheritance is unavailable.
For example, suppose the following Tempate Method pattern:
public abstract class BaseClass {
public void Alpha() {
Beta();
}
public abstract void Beta();
public void Gamma() {
Delta();
}
public abstract void Delta();
}
public ConcreteClass : BaseClass {
public override void Beta() {
Gamma();
}
public override void Delta() {
Console.WriteLine("Delta");
}
}
...
var object = new ConcreteClass();
object.Alpha(); // will outout "Delta"
How can I achieve the same result without ConcreteClass inheriting BaseClass?
Your base class could depend on an interface (or other type) that's injected via the constructor. Your template method(s) could then use the methods on this interface/type to achieve the pattern's desired outcome:
public class BaseClass
{
IDependent _dependent;
public BaseClass(IDependent dependent)
{
_dependent = dependent;
}
public void Alpha() {
_depdendent.Beta();
}
public void Gamma() {
_depdendent.Delta();
}
}
Effectively using composition rather than inheritance.
You can achieve this by providing a reference to the base class on method call:
public ConcreteClass {
public void Beta(BaseClass baseClass) {
baseClass.Gamma();
}
public void Delta() {
Console.WriteLine("Delta");
}
}
I'm using Ninject.Extensions.Interception (more specifically, InterceptAttribute) and Ninject.Extensions.Interception.Linfu proxying to implement a logging mechanism in my C# app, but I am facing some problems when a proxied class implements several interfaces.
I've a class which implements an interface and inherits from an abstract class.
public class MyClass : AbstractClass, IMyClass {
public string SomeProperty { get; set; }
}
public class LoggableAttribute : InterceptAttribute { ... }
public interface IMyClass {
public string SomeProperty { get; set; }
}
public abstract class AbstractClass {
[Loggable]
public virtual void SomeMethod(){ ... }
}
When I try to get an instance of MyClass from ServiceLocator, the Loggable attribute causes it to return a proxy.
var proxy = _serviceLocator.GetInstance<IMyClass>();
The problem is the proxy returned only recognizes the AbstractClass interface, exposing SomeMethod(). Consequentially, I receive an ArgumentException when I try to access the inexistent SomeProperty.
//ArgumentException
proxy.SomeProperty = "Hi";
In this case, is there a way of using mixin or some other technique to create a proxy exposing multiple interfaces?
Thanks
Paulo
I ran in a similar problem and i did not found a elegant solution with only ninject means. So i tackled the problem with a more basic pattern from OOP: composition.
Applied to your problem something like this would be my suggestion:
public interface IInterceptedMethods
{
void MethodA();
}
public interface IMyClass
{
void MethodA();
void MethodB();
}
public class MyInterceptedMethods : IInterceptedMethods
{
[Loggable]
public virtual void MethodA()
{
//Do stuff
}
}
public class MyClass : IMyClass
{
private IInterceptedMethods _IInterceptedMethods;
public MyClass(IInterceptedMethods InterceptedMethods)
{
this._IInterceptedMethods = InterceptedMethods;
}
public MethodA()
{
this._IInterceptedMethods.MethodA();
}
public Method()
{
//Do stuff, but don't get intercepted
}
}
I have an two interfaces defined as follows:
public interface IFoo
{
...
}
Public interface IFooWrapper<T> where T : IFoo
{
T Foo {get;}
}
I want to be able to declare a collection of IFooWrappers but I don't want to specify the implementation of IFoo.
Ideally I want to do something like the:
IList<IFooWrapper<*>> myList;
I can't figure out a way around this.
public interface IFoo
{
...
}
public interface IFooWrapper : IFoo
{
...
}
public interface IFooWrapper<T> : IFooWrapper
where T : IFoo
{
...
}
IList<IFooWrapper> myList;
this is a way to do what you want
What's wrong with
IList<IFooWrapper<IFoo>> myList?
public class FooWrapper : IFooWrapper<IFoo>
What I'm about to suggest is overkill for most situations, since usually you can create an interface higher up in the hierarchy that you can use. However, I think this is the most flexible solution in some ways, and the most faithful representation of what you want:
public interface IFooWrapperUser<U> {
U Use<T>(IFooWrapper<T> wrapper);
}
public interface IFooWrapperUser {
void Use<T>(IFooWrapper<T> wrapper);
}
public interface IExistsFooWrapper {
U Apply<U>(IFooWrapperUser<U> user);
void Apply(IFooWrapperUser user);
}
public class IExistsFooWrapper<T> : IExistsFooWrapper {
private IFooWrapper<T> wrapper;
public IExistsFoo(IFooWrapper<T> wrapper) {
this.wrapper = wrapper;
}
public U Apply<U>(IFooWrapperUser<U> user) {
return user.Use(foo);
}
public void Apply(IFooWrapperUser user) {
user.Use(foo)
}
}
Now you can create an instance of an IList<IExistsFooWrapper> which can be used as if it's an IList<IFooWrapper<*>>. The downside is you'll need to create a class to encapsulate the logic you want to run on each element:
private class FooPrinter : IFooWrapperUser<string> {
public string Apply<T>(IFooWrapper<T> wrapper) {
return wrapper.Foo.ToString();
}
}
...
IFooWrapperUser<string> user = new FooPrinter();
foreach (IExistFooWrapper wrapper in list) {
System.Console.WriteLine(wrapper.Apply(user));
}
...