I have a lot of different engines that implement different algorithms. All of them implement the same interface but have different Configuration methods. Most of them are configured without parameters, some of them with one integer and even less with two integers. There is a small probability that in the future we will have with three or even four integers.
I need to create a Engine controller that decides when it has to start or stop the engine as this is common for all of them. The options I thought are the following:
Create an unique interface with as much parameters as the biggest Configure method available and ignore the not needed ones at the engines. This way I'll have just only one EngineController.
Create an Interface for each of the different configure methods and create a EngineController for each one of the different interfaces (but this will make me create a lot of classes that only differ on the number of parameters and will require 2 new classes each time a new parameter is added to an engine.
...
I really don't feel comfortable with any of the two solutions as passing unneeded parameters looks 'ugly' and due to the high number of classes generated with the second option (that only have very minor differences).
Any design or pattern that avoids this problem?
EDIT (Thanks for the answers, this edit answers all of them and clarifies the question):
Just to give an example, these are the engines.
abstract class EngineBase
{
public void Start() {...}
public void Stop() {...}
}
class EngineOne : EngineBase
{
public void Configure(int parameter1) {...};
}
class EngineTwo : EngineBase
{
public void Configure(int parameter1, int parameter2) {...};
}
class EngineThree : EngineBase
{
public void Configure(int parameter1, int parameter2, int parameter3) {...};
}
As all the engines have the same logic to decide when to start or end I want to create a new class that handles them, called EngineController. The controller will call the Configure, the Start and the Stop when needed:
class EngineController
{
EngineBase _engine; ??? or what?
void SuperviseEngine() { ... _engine.Configure(x,x,...) ... _engine.Start() ...
}
The first idea I has is to add to the EngineBase class the next method:
abstract class EngineBase
{
public void Start() {...}
public void Stop() {...}
public void Configure(int parameter1, int parameter2, int parameter3) {...}
}
class EngineController
{
EngineBase _engine;
void SuperviseEngine() { ... _engine.Configure(x,y,z) ... _engine.Start() ...
}
and ignore the unneeded parameters but I don't like the idea. Then I thought on doing the following:
interface I1ParameterConfigurable
{
public void Configure(int parameter1) {...};
}
interface I2ParameterConfigurable
{
public void Configure(int parameter1, int parameter2) {...};
}
interface I3ParameterConfigurable
{
public void Configure(int parameter1, int parameter2, int parameter3) {...};
}
and then create 3 different controllers for each kind of engine:
class EngineController1Parameter
{
EngineBase _engine;
I1ParameterConfigurable _configurableEngine = _engine as I1ParameterConfigurable;
void SuperviseEngine() { ... _configurableEngine .Configure(x) ... _engine.Start()
}
class EngineController2Parameter
{
EngineBase _engine;
I2ParameterConfigurable _configurableEngine = _engine as I2ParameterConfigurable;
void SuperviseEngine() { ... _configurableEngine .Configure(x, y) ... _engine.Start()
}
You get the idea, but I feel that this will create a lot of interfaces / classes when maybe there is way to avoid this.
Thanks to your answers I have a third option that is similar to the 1st one but using an array (or IEnumerable or whatever) to pass a undefined number of parameters. The idea is not bad but then I'll lose the parameter names. But maybe it's the best option until now.
Will that help you.
interface IEngine
{
void startEngine(params int[] engineParam);
}
Maybe I don't fully understand but I think you want something like this:
public interface IEngineController //I dont see a need to expose the enigine here in this pseudo code
{
void Start();
IConfiguration Config { get; }
}
public interface IEngine
{
void Start();
}
public interface IConfiguration
{
bool IsOkToStart { get; }
}
public class Configuration : IConfiguration
{
public Configuration(List<IConfigurationParameter> configurationParameters)
{
ConfigurationParameters = configurationParameters;
}
public bool IsOkToStart
{
get { return ConfigurationParameters.All(cfg=>cfg.IsOkToStart); }
}
protected List<IConfigurationParameter> ConfigurationParameters { get; private set; }
}
public interface IConfigurationParameter
{
bool IsOkToStart { get; }
}
public interface IMaxTemp : IConfigurationParameter
{
double MaxTemp { get; }
}
public interface ISafetyParameter : IConfigurationParameter
{
ISafetyCondition SafetyCondition { get; }
}
This got a little long, I omitted Stop() for brevity. The idea is:
The controller has an IEngine (not exposed in the interface) and an IConfig
IEngine has the Start() method.
A Configuration is a list of IConfigparameters that has a bool is ok to start (if all parameters are ok).
Each parameter has an IsOkToStart that is calculated depending on some condition
Maybe this provides flexibility for you? Combine the parameters you need and possibly add ned parameters in the future. I believe it is a good thing that the interfaces are extremely small and cohesive. Maybe even split them into IStartParameter and IStopParameter and just combine to the desired config?
I would model it similar to this:
public interface IEngine1 {
}
public interface IEngine1Config {
int Param1 {get;}
}
public Engine1 : IEngine1 {
IEngine1Config _config;
public Engine1(IEngine1Config config) {
_config = config;
}
}
You could then optionally choose to have one class implementing the different engine configurations:
class AllEnginesConfig : IEngine1Config, IEngine2Config {
int Param1 {get;set;}
// ... etc
}
(of course, it may be better in your situation to implement the configs in separate classes also)
If you have a lot of engines, I would use an IoC container to register all the different types, and let it wire up all the dependencies.
container.Register<IEngine1, Engine1>();
var theOneAndOnlyConfig = new AllEnginesConfig() {}; // properly initialized, of course
container.RegisterInstance<IEngine1Config>(theOneAndOnlyConfig);
container.RegisterInstance<IEngine2Config>(theOneAndOnlyConfig);
// ...
Then, to instantiate an engine, you simply use the container:
container.Get<IEngine1>();
IOC containers to invoke a engine you require or bunch of engines you require and inject them at run time and you can use them in combination with optional parameters while invoking containers. I have seen usage of Optional parameters in many attributes of .NET FW. or use an list of object parameter to get all inputs and when called can parse the list and decide which engine it was intended to invoke. None of them will be hard to grasp and use
Related
I've made a class with T. It looks like this.
public interface ISendLogic<T> where T : NarcoticsResult
{
ChangeType Change_New();
ChangeType Change_Cancel();
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
public class SendLogic<T> : ISendLogic<T> where T : NarcoticsResult
{
private eReportType _type;
private bool Send_Change()
{
// Send to server by xml file
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public ChangeType Change_New()
{
_type = change_new;
Send_Change();
}
public ChangeType Change_Cancel()
{
_type = change_cancel;
Send_Change();
}
public PurchaseType Purchase_New()
{
_type = purchase_new;
Send_Purchase();
}
public PurchaseType Purchase_Cancel()
{
_type = purchase_cancel;
Send_Purchase();
}
}
There are two types, ChangeType and PurchaseType
and these are inherited from NarcoticsResult.
I thought the person who want to use this class would use it like this.
// this class can only be used when someone wants to use change function
var logic = SendLogic<ChangeType >();
logic.Change_New();
logic.Change_Cancel();
Here is a question.
I want to force this class to be used only as I thought.
I mean, I want to prevent it to be used like this.
var logic = SendLogic<ChangeType>();
logic.Change_New(); // OK
logic.Purchase_New(); // You should make this class like SendLogic<PurchaseType>()
I thought I add some code which check type of T in every function.
How do you think the way I thought. I think there are better way to fix it
Please tell me a better way
thank you.
Personally, I don't think you need a generic class in this case. What you need is either an abstract base class or an interface. I personally love the interface approach as below:
public interface ISendLogic {
void New();
void Cancel();
}
So now you've got a contract that will force the consumer of your code to use New or Cancel methods only.
The next step you can implement that send logic interface for your specific implementation:
public class ChangeSendLogic : ISendLogic {
private eReportType _type;
public ChangeSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Change()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Change();
}
public void Cancel()
{
_type = change_cancel;
Send_Change();
}
}
public class PurchaseSendLogic : ISendLogic {
private eReportType _type;
public PurchaseSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Purchase();
}
public void Cancel()
{
_type = change_cancel;
Send_Purchase();
}
}
From here you can see those two classes handle the implementation for each type nicely. You can think this is as an implementation of single responsibility principle. So if you have one more type, you can just add one more implementation of this interface rather than updating the existing classes.
If you want to hide the creation of those objects, in the next part you can introduce a kind of factory or selector as below:
public enum SendLogicType {
Change,
Purchase
}
public static SendLogicSelector {
public static ISendLogic GetSendLogic(SendLogicType type)
{
switch(type)
{
case SendLogicType.Change:
return new ChangeSendLogic();
case SendLogicType.Purchase:
return new PurchaseSendLogic();
}
}
}
This is how the code will be consumed:
ISendLogic sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Change);
sendLogic.New(); // change new logic executed
sendLogic.Cancel(); // change cancel logic executed
sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Purchase);
sendLogic.New(); // purchase new logic executed
sendLogic.Cancel(); // purchase cancel logic executed
Hopefully, you can get the idea of my approach. Good luck! :)
Thank you for your comment
I divided it into two parts like below
public class ChangeSendLogic : SendLogic<ChangeType>, IChangeLogic
public class PurchaseSendLogic : SendLogic<PurchaseType>, IPurchaseLogic
And I also divided interface too
public interface IChangeLogic
{
ChangeType Change_New();
ChangeType Change_Cancel();
}
public interface IPurchaseLogic
{
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
And I made SendLogic<T> class to abstract class.
This is because I want to make the person who wants to use this class to use a class that inherits from this class without directly accessing it.
Thank you for your comment. I got a good idea.
I want to integrate my application with X number of external systems. The integration with each external system will have same kind of actions but will be handled in a separate classes.
Hence the aim to define an interface that will make sure all integration classes conform to certain actions. e.g.
public interface IOrderIntegration
{
//I want to define the ImportOrder action here, so that all future integrations conform
}
However each external system has its own closed SDK (cannot be edited) that needs to be referenced. e.g
public class EbayOrderIntegration : IOrderIntegration
{
void ImportOrder(Ebay.SDK.Order order)
{
//Logic to import Ebay's order
}
}
public class AmazonOrderIntegration : IOrderIntegration
{
void ImportOrder(Amazon.SDK.Order order)
{
//Logic to import Amazon's order
}
}
Is there a way to still use an interface in this case to ensure all integrations perform a certain action? Or perhaps another pattern ?
This is where generics come intp play:
public interface IOrderIntegration<T>
{
void ImportOrder(T order);
}
public class EbayOrderIntegration : IOrderIntegration<Ebay.SDK.Order order>
{
void ImportOrder(Ebay.SDK.Order order order)
{
// ...
}
}
Another way than HimBromBeere's answer (great answer by the way !). Note that this can only work if you can abstract at the order level:
public class OrderIntegration
{
public void ImportOrder(IOrder order)
{
// Only possible if you can abstract all the logic into IOrder
}
}
public interface IOrder
{
// Abstract here the order logic
}
public class EbayOrder : IOrder
{
public EbayOrder(Ebay.SDK.Order order)
{ .. }
}
public class AmazonOrder : IOrder
{
public AmazonOrder(Amazon.SDK.Order order)
{ .. }
}
The choice between HimBromBeere's anwser and mine will depend on where you want to (and can!) abstract your different providers and how you want to use your API.
Maybe overloading a method is not exactly what is necessary but this is the best i could come up with.
I have a class:
public class Worker {
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
}
public void ProcessJob()
{
if(jobType.Equals("Pizza") MakePizza();
else if (jobType.Equals("Burger") MakeBurger();
}
private void MakePizza()
{
// make pizza
}
private void MakeBurger()
{
// make burger
}
}
The above is just an example of illustration. When the class is constructed, it is constructed with a specific job type, and that won't change. However it may need to perform millions of jobs, always of the same type. The ProcessJob() will be called all the time, but the caller won't know what type of worker this is. I would like to avoid running the if check every single time, there has to be a way to do that check only once and prep it.
In my case, making child classes (pizza worker, burger worker, etc.) is not an option, as in my real case, the class is large and there is only one tiny difference. Changing it will impact the whole architecture so it needs to be avoided.
Create an abstract base class, which contains common things a worker can do. Then declare derived classes for specialized workers.
public abstract class Worker
{
public abstract void ProcessJob();
}
public class PizzaWorker : Worker
{
public override void ProcessJob()
{
// Make pizza
}
}
public class BurgerWorker : Worker
{
public override void ProcessJob()
{
// Make burger
}
}
Now you can create workers of different types and let them do their job:
var workers = new List<Worker>();
workers.Add(new PizzaWorker());
workers.Add(new BurgerWorker());
foreach (Worker worker in workers) {
woker.ProcessJob();
}
This will automatically call the right implementation of ProcessJob for each type of worker.
Note: If-else-if cascades and switch statements are often an indication that the code works in a procedural rather than object-oriented way. Refactor it to be object-oriented!
You could use a delegate created when the object is constructed, this way the dispatch is done automatically:
public class Worker
{
private delegate void MakeSomething();
private MakeSomething makeWhat;
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
switch (jt)
{
case "Pizza":
makeWhat = new MakeSomething(MakePizza);
break;
case "Burger":
makeWhat = new MakeSomething(MakeBurger);
break;
default:
throw new ArgumentException();
}
}
public void ProcessJob()
{
makeWhat();
}
private void MakePizza()
{
//make pizza
}
private void MakeBurger()
{
//make burger
}
}
I would still recommend to use sub classes. If you cannot inherit from Worker then create new class hierarchy that is used inside the worker. This way anyone using Worker class doesn't have to know that there are sub classes. If you really really hate sub classes or you have some other reason you don't want them you can use dictionary. It contains job type as key and Action as the method it calls. If you need more jobs just create the private method and register it in the RegisterWorkers method.
private Dictionary<string, Action> actions = new Dictionary<string, Action>();
public Worker(string jt)
{
this.jobType = jt;
this.RegisterWorkers();
}
private void RegisterWorkers
{
this.actions["Pizza"] = this.MakePizza;
this.actions["Burger"] = this.MakeBurger;
}
public void ProcessJob()
{
var action = this.actions[this.jobType];
action();
}
No, I don't think it should be avoided. Any common functionality should go in a base class. I think you need a static factory method, that returns a child class based on the string parameter.
public abstract class Worker {
public virtual void ProcessJob();
public static Worker GetWorker(string jobType) {
if(jobType.Equals("Pizza")
return new PizzaWorker();
else if (jobType.Equals("Burger")
return new BurgerWorker();
else
throw new ArgumentException();
}
// Other common functionality
protected int getFoo() {
return 42;
}
}
public class PizzaWorker : Worker {
public override void ProcessJob() {
// Make pizza
int y = getFoo() / 2;
}
}
public class BurgerWorker : Worker {
public override void ProcessJob() {
// Make burger
int x = getFoo();
}
}
So to use this:
Worker w = Worker.GetWorker("Pizza");
w.ProcessJob(); // A pizza is made.
This is exactly why there are patterns: Command, Strategy, Decorator.
I believe the command pattern is what you are looking for. First you have a basic 'command' template:
public interface IJob {
void ProcessJob();
}
Different jobs would then be performed as follows:
public class MakePizza : IJob {
// implement the interface
public void ProcessJob() {
// make a pizza
}
}
Now, you could have a JobFactory as follows:
public static class JobFactory {
public static IJob GetJob(string jobType) {
if(jobType.Equals("Pizza"){
return new MakePizza();
} else (jobType.Equals("Burger") {
return new MakeBurger();
}
// to add jobs, extend this if-else-if or convert to switch-case
}
}
Worker can now look like this:
public class Worker {
private IJob job;
public Worker(string jt) {
job = JobFactory.GetJob(jt);
}
public void ProcessJob() {
job.ProcessJob();
}
}
If you don't have access to code to make these changes, then another pattern you may want to look into is the Adapter.
You're talking about basic inheritance here. There are a couple of ways that you could do this.
Make a Base Class that is
public class Job
{
virtual void ProcessJob();
}
Then a MakePizza class
public class MakePizza : Job
{
public void ProcessJob()
{
//make Pizza
}
}
Then in your worker class instead of having a JobType as a string which will lead to all kinds of potential bugs.
public class Worker{
private Job jobType;
public Worker(Job jt){
this.jobType = jt;
}
public void ProcessJob()
{
Job.ProcessJob();
}
}
If you have to pass through a string you could simply load up the JobType through reflection, throwing a error if the type doesn't exist.
having to change other classes means you need to change code, not that you need to change architecture. the best answer is just to change the code. in the long term, the maintenance burden of having to write this in a less-than-ideal fashion will cost you more than just changing the code. use inheritance and bite the bullet on making the change now. if you have iterators that will have problems with dealing with subtypes, your iterators are doing more than being iterators, and you are better off fixing that than going forward with them. if the other classes care about what subtype of worker they are dealing with, that's a problem in and of itself that you should fix. ultimately, the dependent code should not care which type of worker it is. that's really what you are after anyway. the instance of a type that has work as its base type is still a worker and that is all the class using a worker should care about.
I have 2 cases wheter a method can be considered a Factory Design Pattern, this example is in C#, altought, can apply to other programming languages:
enum NinjaTypes {
Generic,
Katanna,
StarThrower,
Invisible,
Flyer
}
public class Ninja {
public string Name { get; set; }
public void jump() { ... }
public void kickAss() { ... }
}
public class KatannaNinja: Ninja {
public void useKatanna() { ... }
}
public class StarNinja: Ninja {
public void throwStar() { ... }
}
public class InvisibleNinja: Ninja {
public void becomeInvisible() {...}
public void becomeVisible() {...}
}
public class FlyNinja: Ninja {
public void fly() {...}
public void land() {...}
}
public class NinjaSchool {
// always return generic type
public Ninja StandardStudent() {...}
// may return other types
public Ninja SpecialityStudent(NinjaTypes WhichType) {...}
}
The method StandardStudent() always return a new object of the same type, the SpecialityStudent(...), may return new objects from different classes that share the same superclass / base type. Both methods are intentionally not virtual.
The question is, are both methods "Factory Design Pattern" ?
My guess is that SpecialityStudent(...) is, but StandardStudent() is not. If the second is not, can be considered another design pattern ?
I don't think that nor a FactoryMethod`nor AbstractFactory patterns forbid the user to use a parameter to specify a type to the creator method. Anyway you should consider at least 2 things in your design:
Factory methods are useful to keep the client unaware of the concrete type of the created object. From my point of view isn't wrong to specify explicitly the type of object to be created, but pay attention to not put too much knowledge on the client classes to be able to construct objects through the factory.
Both your factory methods return a Ninja object, but some of your ninjas extended class declare additional methods, which client is unaware of. If your client need to use those methods explicitly then maybe you have to make some consideration on your design.
I think this actually looks like an Anti-Pattern. There's really nothing to stop a consumer of this code to just instantiate the specialty ninjas directly. What benefit is there to using the Ninja School? I think the whole point of the Factory pattern is to encapsulate the process of instantiating an object so that you can hide the details from the consumer. Any time you make a change to the "creation" logic, it doesn't break anyone's code.
And it just looks like a bad idea to have all the types in an enum. I don't have a concrete reason to back up this claim other than, "it feels wrong".
After reviewing the Abstract Factory pattern, I can see how you could go about turning this into an Abstract Factory, but I don't see the benefit given the semantics of your objects. I think that if you want to have a Ninja factory, you'd have to make the individual constructors protected or internal, so they can't be called directly by consumer code
Both your methods can be seen as factories. But the second one is a little awkward to use:
var school = new NinjaSchool();
var ninja = school.SpecialtyStudent(NinjaTypes.Flyer);
// to fly you must cast
((FlyingNinja)ninja).Fly();
You've already asked for a flyer, so you shouldn't need to cast. A better option might be to eliminate the enum and ask for the exact ninja that you want:
var flyingNinja = school.FlyingStudent(); // you get a FlyingNinja
flyingNinja.Fly();
Another thing to consider in your design is this: what if you want an invisible ninja that can fly? Or a katana ninja that also throws stars? That will shake up your hierarchy and challenge your belief in inheritance.
It's almost a factory method. I would do something like:
enum NinjaTypes {
Generic, Katanna, StarThrower, Invisible, Flyer
}
class Ninja {
String Name;
void jump() {
}
void kickAss() {
}
void useKatanna() {
System.out.println("nothing happens");
}
void throwStar() {
System.out.println("nothing happens");
}
void becomeInvisible() {
System.out.println("nothing happens");
}
void becomeVisible() {
System.out.println("nothing happens");
}
void fly() {
System.out.println("nothing happens");
}
void land() {
System.out.println("nothing happens");
}
}
class StarThrowerNinja extends Ninja {
void throwStar() {
System.out.println("throwing star");
}
}
class NinjaSchool {
static Ninja create(NinjaTypes WhichType) {
switch (WhichType) {
case Generic:
return new Ninja();
case StarThrower:
return new StarThrowerNinja();
default:
return null;
}
}
}
public class Main {
public static void main(String[] args) {
Ninja generic=NinjaSchool.create(NinjaTypes.Generic);
generic.throwStar();
Ninja starThrower=NinjaSchool.create(NinjaTypes.StarThrower);
starThrower.throwStar();
}
}
I have a class that gets used in a client application and in a server application.
In the server application, I add some functionality to the class trough extension methods. Works great. Now I want a bit more:
My class (B) inherits from another class (A).
I'd like to attach a virtual function to A (let's say Execute() ), and then implement that function in B. But only in the server. The Execute() method would need to do stuff that is only possible to do on the server, using types that only the server knows about.
There are many types that inherit from A just like B does, and I'd like to implement Execute() for each of them.
I was hoping I could add a virtual extension method to A, but that idea doesn't seem to fly. I'm looking for the most elegant way to solve this problem, with or without extension methods.
No, there aren't such things as virtual extension methods. You could use overloading, but that doesn't support polymorphism. It sounds like you might want to look at something like dependency injection (etc) to have different code (dependencies) added in different environments - and use it in regular virtual methods:
class B {
public B(ISomeUtility util) {
// store util
}
public override void Execute() {
if(util != null) util.Foo();
}
}
Then use a DI framework to provide a server-specific ISomeUtility implementation to B at runtime. You can do the same thing with a central static registry (IOC, but no DI):
override void Execute() {
ISomeUtility util = Registry.Get<ISomeUtility>();
if(util != null) util.Foo();
}
(where you'd need to write Registry etc; plus on the server, register the ISomeUtility implementation)
You can use the new dynamic type functionality to avoid having to build a registry of types to methods:
using System;
using System.Collections.Generic;
using System.Linq;
using visitor.Extension;
namespace visitor
{
namespace Extension
{
static class Extension
{
public static void RunVisitor(this IThing thing, IThingOperation thingOperation)
{
thingOperation.Visit((dynamic)thing);
}
public static ITransformedThing GetTransformedThing(this IThing thing, int arg)
{
var x = new GetTransformedThing {Arg = arg};
thing.RunVisitor(x);
return x.Result;
}
}
}
interface IThingOperation
{
void Visit(IThing iThing);
void Visit(AThing aThing);
void Visit(BThing bThing);
void Visit(CThing cThing);
void Visit(DThing dThing);
}
interface ITransformedThing { }
class ATransformedThing : ITransformedThing { public ATransformedThing(AThing aThing, int arg) { } }
class BTransformedThing : ITransformedThing { public BTransformedThing(BThing bThing, int arg) { } }
class CTransformedThing : ITransformedThing { public CTransformedThing(CThing cThing, int arg) { } }
class DTransformedThing : ITransformedThing { public DTransformedThing(DThing dThing, int arg) { } }
class GetTransformedThing : IThingOperation
{
public int Arg { get; set; }
public ITransformedThing Result { get; private set; }
public void Visit(IThing iThing) { Result = null; }
public void Visit(AThing aThing) { Result = new ATransformedThing(aThing, Arg); }
public void Visit(BThing bThing) { Result = new BTransformedThing(bThing, Arg); }
public void Visit(CThing cThing) { Result = new CTransformedThing(cThing, Arg); }
public void Visit(DThing dThing) { Result = new DTransformedThing(dThing, Arg); }
}
interface IThing {}
class Thing : IThing {}
class AThing : Thing {}
class BThing : Thing {}
class CThing : Thing {}
class DThing : Thing {}
class EThing : Thing { }
class Program
{
static void Main(string[] args)
{
var things = new List<IThing> { new AThing(), new BThing(), new CThing(), new DThing(), new EThing() };
var transformedThings = things.Select(thing => thing.GetTransformedThing(4)).Where(transformedThing => transformedThing != null).ToList();
foreach (var transformedThing in transformedThings)
{
Console.WriteLine(transformedThing.GetType().ToString());
}
}
}
}
I would suggest something like the following. This code could be improved by adding support for detecting intermediate class hierarchy types that don't have a dispatch mapping and calling the nearest dispatch method based on the runtime hierarchy. It could also be improved by using reflection to detect overload of ExecuteInteral() and adding them automatically to the dispatch map.
using System;
using System.Collections.Generic;
namespace LanguageTests2
{
public class A { }
public class B : A {}
public class C : B {}
public static class VirtualExtensionMethods
{
private static readonly IDictionary<Type,Action<A>> _dispatchMap
= new Dictionary<Type, Action<A>>();
static VirtualExtensionMethods()
{
_dispatchMap[typeof(A)] = x => ExecuteInternal( (A)x );
_dispatchMap[typeof(B)] = x => ExecuteInternal( (B)x );
_dispatchMap[typeof(C)] = x => ExecuteInternal( (C)x );
}
public static void Execute( this A instance )
{
_dispatchMap[instance.GetType()]( instance );
}
private static void ExecuteInternal( A instance )
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
private static void ExecuteInternal(B instance)
{
Console.WriteLine( "\nCalled ToString() on: " + instance );
}
private static void ExecuteInternal(C instance)
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
}
public class VirtualExtensionsTest
{
public static void Main()
{
var instanceA = new A();
var instanceB = new B();
var instanceC = new C();
instanceA.Execute();
instanceB.Execute();
instanceC.Execute();
}
}
}
Virtual implies inheritance in a OOP way and extension methods are "just" static methods that through a bit a syntactic sugar the compiler allows you to pretend to call on an instance of the type of its first parameter. So no, virtual extension methods are out of the question.
Check out the answer by Marc Gravell for a possible solution to your problem.
You can implement a service register. Example (server side):
static IDictionary<Type, IService> serviceRegister;
public void ServerMethod(IBusinessType object)
{
serviceRegister[obect.GetType()].Execute(object);
}
What you need are rather services in your server, which implement server side functionality, instead of extension methods. I wouldn't put to much logic into extension methods.
Let me check: you have a class hierarchy inheriting from A, presumably structured according to your business domain. Then you want to add behaviours depending on where the classes execute. So far you've used extension methods, but now you find you cannot get them to vary with your class hierarchy. What kinds of behaviours are you attaching at the server?
If it's stuff like transaction management and security, policies implemented through dependency injection à la Marc's suggestion should work well. You could also consider implementing the Strategy pattern through delegates and lambdas, for a more limited version of DI. However, what's not clear is how client code currently uses your classes and their extension methods on the server. How dependent are other classes on how you add the server-side functionality? Are they server-side only classes that currently expect to find the extension methods?
In any case, it sounds like you're going to need a careful testability design and testing strategy since you are introducing variation along two simultaneous dimensions (inheritance hierarchy, execution environment). You are using unit testing, I trust? Check that whatever solution you choose (e.g. DI through configuration) interacts well with testing and mocking.