I am developing a C# library where the user needs to write his/her own classes inheriting from given classes from the library. I don't think writing further details will be helpful, so please even if what I am asking for looks strange, consider it as such.
In one class, I would like the following behavior: two mutually exclusive "abstract" methods such that if one is implemented then there is no need to implement the other (so right, they are not really abstract).
I need to force the user to implement at least one of these methods, so declaring both methods virtual only is not enough. Actually I could declare both abstract, but it means the user should implement a method that would never be called afterwards and of course I want to avoid that.
Is there a trick or a C# idiom to do something close to what I want? Maybe with some reflection tricks I know almost nothing about?
I think what you're trying to do is violating a lot of Object-Oriented design goals.
"I need to force the user to implement at least one of these methods"
If the two classes need to have functionality that is is one thing or the other, why not just have 1 abstract method (or create an interface), and have the two classes override that method differently? Then you force each class to implement one part of the functionality and the other implement the other type.
I would recommend re-thinking your approach rather than spending tons of time trying to make a poor approach work.
EDIT:
Based on your comments I'll try to go into a bit more detail.
You could try something like the following. But I suspect you'll need to expand it significantly to get it working. But this should get you started anyway
public class ResultFromMethod1 {
public bool optimized = false;
// other results here
}
This stores the results from method 1 and tells you how method 1 was run.
public interface IInterfaceForMethod1 {
ResultFromMethod1 Method1 ();
}
public interface IInterfaceForMethod2 {
void Method2 (ResultFromMethod1 resultFromMethod1, Vector v);
}
These are the interfaces for the two methods. Note that they are not implemented yet. This is just a contract for classes that implement them.
public class UnoptomizedImplementation : IInterfaceForMethod1, IInterfaceForMethod2 {
#region IInterfaceForMethod1 implementation
public ResultFromMethod1 Method1 () {
ResultFromMethod1 resultFromMethod1 = new ResultFromMethod1 ();
resultFromMethod1.optimized = false;
// Method1 logic here
return resultFromMethod1;
}
#endregion
#region IInterfaceForMethod2 implementation
public void Method2 (ResultFromMethod1 resultFromMethod1, Vector v) {
if (!ResultFromMethod1.optimized) {
//if NOT optimized
//logic here
}
else {
//throw exception
}
}
#endregion
}
These class runs method1 not optimized, and then has a method2 that requires method 1 be not optimized. If you don't need method2 when it's not optimized then just don't implement the method2 interface.
public class OptimizedImplementation : IInterfaceForMethod1, IInterfaceForMethod2 {
#region IInterfaceForMethod1 implementation
public ResultFromMethod1 Method1 () {
ResultFromMethod1 resultFromMethod1 = new ResultFromMethod1 ();
resultFromMethod1.optimized = true;
// Method2 logic here
return resultFromMethod1;
}
#endregion
#region IInterfaceForMethod2 implementation
public void Method2 (ResultFromMethod1 resultFromMethod1, Vector v) {
if (ResultFromMethod1.optimized) {
//if optimized
//logic here
}
else {
//throw exception
}
}
#endregion
}
This class requires an output from method1 that is optimized or it throws an exception.
I hope that sends you down a more manageable track.
I suggest implementing interfaces
public interface IMyMethod1 {
void MyMethod1();
}
public interface IMyMethod2 {
void MyMethod2();
}
and inject a dependency
public class MyClass {
...
public MyClass(IMyMethod1 method1, IMyMethod2 method2) {
if ((null == method1) && (null == method2))
throw new ArgumentNullException("method1",
"You should provide either method1 or method2");
m_Method1 = method1;
m_Method2 = method2;
}
...
public void DoSomething() {
...
if (m_Method1 != null)
m_Method1.MyMethod1();
else if (m_Method2 != null)
m_Method2.MyMethod2();
...
}
}
To avoid reflection, create you base class (abstract) without either of those two methods.
Then, create separate classes (abstract) inheriting your base class for both of the "special" methods.
This will require some type-checking and casting, but it's all I got right now.
Related
once again I'm here for help. I'm writing my first "real-like" application to practice what I learned and I am not sure about my approach. I'll try to explain it as best as my english allows me.
Application consist of base abstract class and three classes inherited from that base.
abstract class BaseClass
{
// Some stuff...
// This method is used in all classes. It gets whole adb output
// and returns it as a string for future formating
protected string ProcessAdbCommand(string command)
{
try
{
_processInfo.Arguments = command;
Process adbProcess = Process.Start(_processInfo);
adbProcess.WaitForExit();
return adbProcess.StandardOutput.ReadToEnd();
}
catch (Exception e)
{
WriteToLog(e.Message);
return null;
}
}
}
After ProcessAdbCommand returns output, I will call another method which handles output as needed. Principle is always the same - format output and make somethinkg usefull based on the output.
Now I'd like to make clear, that method responsible for output handling needs to be in every inherited class. But problem is that in very class it returns different value type (boolean, List of IDevice and strings)
I am struggling here. First I wanted to make it protected abstract. Somethink like
abstract class BaseClass
{
// Some stuff...
// Same as above
protected string ProcessAdbCommand(string command)
{
//Same as above
}
//Method which will be implemented in every inherited class differently
protected bool|List<IDevice>|string ProcessAdbOutput(string adbOutput)
{
//Method implementation
return bool|List<IDevice>|string
}
}
But as I discovered it is not possible to override return type. And because method will be always used only internally in classes, I do not see reason to "force" it using interfaces.
After some time I game up and decided to forget about forcing implementation in derived classes and simply write them as I need. But do you think it is "legal" approach? How would you solve problem like that in "real world" application? Is there something I am still missing or is my approach simply wrong? Thank you.
Struggling Greenhorn.
One possible approach would be to make the abstract base class generic and accept a T parameter, which can also be the output of your ProcessAdbOutput method. Then, you make the method abstract to make sure any derived type has to implement it:
public abstract class BaseClass<T>
{
protected string ProcessAdbCommand(string command)
{
return string.Empty;
}
public abstract T ProcessAdbOutput(string result);
}
public class DerivedClass : BaseClass<IList<IDevice>>
{
public override IList<IDevice> ProcessAdbOutput(string result)
{
return new List<IDevice>();
}
}
I heard the word Interface Duck Typing, but do not understand at all what is it? So I read a wiki about this and they said:
In computer programming with object-oriented programming languages, duck typing is a style of typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of an explicit interface. The name of the concept refers to the duck test.
But still could not understand what it. So I saw their program but they use dynamic keyword to call quack() & feather() function of all the classes.
I would request you all please explain in easy way what is Interface Duck Typing and how to implement in C# v2.0 because there is no dynamic keyword.
using System;
namespace DuckTyping
{
public class Duck
{
public void Quack()
{
Console.WriteLine("Quaaaaaack!");
}
public void Feathers()
{
Console.WriteLine("The duck has white and gray feathers.");
}
}
public class Person
{
public void Quack()
{
Console.WriteLine("The person imitates a duck.");
}
public void Feathers()
{
Console.WriteLine("The person takes a feather from the ground and shows it.");
}
}
internal class Program
{
private static void InTheForest(dynamic duck)
{
duck.Quack();
duck.Feathers();
}
private static void Game()
{
Duck donald = new Duck();
Person john = new Person();
InTheForest(donald);
InTheForest(john);
}
private static void Main()
{
Game();
}
}
}
C# has a nominal type system, so the compatibility of types is done based on their names. In your example you have two classes with a Quack method, however there is no way to write a method which can take instances of these two classes and invoke their Quack method.
In C# 2, the solution would be to introduce an interface and have both classes implement it:
public interface IQuack
{
void Quack();
}
public class Duck : IQuack { }
public class Human : IQuack { }
now you can create a method which take an IQuack instance and can call Human.Quack and Duck.Quack through it. In C#, methods are resolved 'early' at compile time, so you need to create a named type which supports the operations the method need so the compilation can succeed. Note there is still a runtime element to calling these methods, since the real implementation of IQuack.Quack needs to be resolved at runtime depending on the real type of the argument.
In a duck-typing system, no attempt is made to validate that a method exists before runtime. All that is required is that a given object supports the operation in that it has the right name and takes the required number of parameters (none in this case), hence the 'if it quacks like a duck' expression.
Duck typing in C# 2 can only be done using reflection, in this case you would accept an object argument and look for the required methods yourself:
public static void MakeQuack(object duck)
{
MethodInfo quackMethod = duck.GetType().GetMethod("Quack", Type.EmptyTypes, null);
if (quackMethod!=null)
{
quackMethod.Invoke(duck, new object[] { });
}
else
{
throw new ArgumentException("No Quack() method found on target");
}
}
C#4 makes this much simpler with dynamic:
public static void MakeQuack(dynamic duck)
{
duck.Quack();
}
It would say it is a way of coding where the you tell the compiler:
"Hey trust me I know what methods and properties this object supports. You don't need to check them for me whilst I code."
Once you run your app the compiler will go:
"Ok lets see if I could trust you. Let me do some runtime binding."
If you then made a mistake, such as using an unsupported method, the compiler will shout: "Hey man, this is not supported! Check my RuntimeBinderException!"
Duck typing allows an object to be passed in to a method that expects
a certain type even if it doesn’t inherit from that type. All it has
to do is support the methods and properties of the expected type in
use by the method. I emphasize that last phrase for a reason. Suppose
we have a method that takes in a duck instance, and another method
that takes in a rabbit instance. In a dynamically typed language that
supports duck typing, I can pass in my object to the first method as
long as my object supports the methods and properties of duck in use
by that method. Likewise, I can pass my object into the second method
as long as it supports the methods and properties of rabbit called by
the second method. Is my object a duck or is it a rabbit? Like the
above image, it’s neither and it’s both. In many (if not most) dynamic
languages, my object does not have to support all methods and
properties of duck to be passed into a method that expects a duck.
Same goes for a method that expects a rabbit.It only needs to support
the methods and properties of the expected type that are actually
called by the method.
Please refer this to get an idea about Duck Typing
http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx/
About Duck Typing:
We don't need to know what the object is, but we just want to let the
object do something if it can do.
Example:
Example, if here are the things that we want the following objects do.
PleaseWalk(new Dog());
PleaseRun(new Duck());
PleaseWalk(new Cup());
PleaseFly(new Man());
PleaseFly(new Bird());
And, here is the result after we request the above objects do the things.
So, we don't need to check what the object is, but we can let it do something enough. Here is the code that I have written in C#.
private void PleaseWalk(object obj)
{
string Method = "Walk";
MethodInfo walkMethod = obj.GetType().GetMethod(Method, Type.EmptyTypes, null);
if (walkMethod != null)
{
walkMethod.Invoke(obj, new object[] { });
}
else
{
Console.WriteLine(string.Format("I can not {0} because {1}", Method, WhoAreYou(obj)));
}
}
private string WhoAreYou(object unknown)
{
MethodInfo whoAreYou = unknown.GetType().GetMethod("WhoAreYou", Type.EmptyTypes, null);
return whoAreYou.Invoke(unknown, new object[] { }).ToString();
}
You can use Events and exploit C# best suitable overload functions.
Hopefully, it will be useful :)
To get something Like a duck typing (.Net 4.+):
using System.Collections;
using System.Collections.Generic;
public interface IAny
{
void InvokeGetterEvent();
}
public class AnyValueTypeDuck<T, V> : IAny
where V : AnyValueTypeDuck<T, V>
{
public static event System.Action<V> GetterEvent;
public T Data;
public void InvokeGetterEvent()
{
GetterEvent.Invoke((V)this);
}
}
// Then create some concrete classes:
// Example :
public class LifeConcreteProperty : AnyValueTypeDuck<int, LifeConcreteProperty>
{
}
public class ManaConcreteProperty : AnyValueTypeDuck<float, ManaConcreteProperty>
{
}
// Now to finally use it :
public class UserClass
{
List<IAny> allDuckTypes = new List<IAny>();
public void GetDucketTypeClass(IAny anyDuckObject)
{
LifeConcreteProperty.GetterEvent += GetDucketType;
ManaConcreteProperty.GetterEvent += GetDucketType;
anyDuckObject.InvokeGetterEvent();
// it will propagate to event and will invoke
// best suitable overload method (GetDucketType)
LifeConcreteProperty.GetterEvent -= GetDucketType;
ManaConcreteProperty.GetterEvent -= GetDucketType;
}
public void GetDucketType(LifeConcreteProperty originalClass)
{
// Your efforts go here
int value = originalClass.Data;
}
public void GetDucketType(ManaConcreteProperty originalClass)
{
// Your efforts go here
float value = originalClass.Data;
}
}
In my project, I have many DLL assemblies referenced. One of those DLL's contains the bool method that I want to change. I do not have the original source for the DLL and using a Reflector to decompile a project seems impractical. All I want to do is intercept or override this method or method call so that I can change it's return value to match my own method outside of said DLL.
Any such way to do this? Thanks!
Edit:
Here is an example:
public virtual bool isOwner()
{
return false;
}
Essentially, I just want to change getOwner to return true;
If the class is public and the method is marked as virtual, then you can simply override it with this syntax:
public MyClass : TheClass
{
public override ReturnType MethodName(Arguments)
{
//class the base class implementation if needed
//base.MethodName(Arguments)
//do your own stuff and return whatever is needed
}
}
Hope this helps
EDIT: A word of caution though, this won't replace the calling code within the DLL. It will only work if you instantiate the derived class yourself and call it from your code.
Is there a general way to do what you want, built into .NET?
Yes, and no.
If you want every usage of class X' method Y to be replaced by some other code, then no, there is nothing built into .NET class system or compiler that will do this.
If you can inherit from class X, overriding method Y, and then ensure that all places where class X is used, your new class is used instead, then yes, that is the proper way to do this.
This is easily done:
public class YourFixedClass : TheProblematicClass
{
public override string YourProblematicMethod()
{
// probably call the problematic method through base.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
Or, if you can make a new class that implements all the same interfaces, wrapping (delegating) all the methods and properties of the original (problematic) class, then that might be doable, but this requires all actual usage of the class to go through the interfaces.
As this:
public class Wrapper : IInterface1, IInterface2
{
private readonly YourProblematicClass _C;
public Wrapper(YourProblematicClass c)
{
_C = c;
}
public string YourProblematicMetho()
{
// probably call the problematic method through _C.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
If, on the other hand, you don't have control of where all the code is that calls the class/method, then no, you can't do any of this.
So what else is there? Well, there is always the debugger interfaces. You can make a program that is somehow the debugger of itself, patching in the right code upon demand, but this is likely to be extraordinary difficult to get right.
In short, no, there is no way to do what you want. You need to find a different way to accomplish this.
Have you thought about changing the original assembly in the first place? I understand that you don't have the source code for it, but is that because:
You lost it
You didn't make it
In point 1, I would really work towards recreating the source code, either through a decompiler or similar, and get a new project going to fix that.
In point 2, have you thought about contacting the people that made it and asking them for help?
Uhm Ok you can do something like this:
public class MyNameClass : MyDllname.MyClassName
{
public bool isOwner()
{
return !base.isOwner();
}
}
Then you have override the method and you can use all the other methods in the DLL simply using an istance(if there aren't static) of the MyNameClass
You can use "new" modifier.
See example on http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Or this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ClassA().IsEvenDayToday()); // Result: true
Console.WriteLine(new ClassB().IsEvenDayToday()); // Result: false
Console.ReadKey();
}
}
public class ClassA : ClassB
{
public new bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 == 0;
}
}
public class ClassB
{
public bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 != 0;
}
}
I currently have method which is trying to find out what the obj is it recieved. It knows is on a certain interface, for example IService but I have code which looks at it and tries to tell me is it is for example Service1 or Service2.
I currently a lot of if(obj is thisObj) style statements, what would be the best solution to make this code pretty?
here is a sample of what exactly I have:
public void DoSomething(IService service)
{
if (service is Service1)
{
//DO something
}
if (service is Service2)
{
//DO something else
}
}
now having two isnt too much of a bad thing, but I am looking at having probably 20+ of these which just becomes awful to use.
Any ideas?
ok further details I think are needed and here they are:
prior to this method I have another method which is recieving a xml doc, which it them deserializes into the interface IService, so we have something like this:
private static void Method(InnerXml)
{
var messageObj = (IServiceTask)XmlSerialization.Deserialize(typeof(IServiceTask), InnerXml);
var service = GetService(messageObj);
service.PerformTask(xmlDoc);
}
private static IService GetService(IServiceTask messageObj)
{
var service = new IService ();
if (messageObj is Task1)
{
service = (SomeService)messageObj;
}
if (messageObj is Task2)
{
service = (SomeOtherService)messageObj;
}
return service ;
}
Hopefully that makes it a bit clearer.
Can you change IService ?
Add method DoSomething() and implement it in all the services.
Well, it depends on what the //DO something lines are doing. In some cases it would be appropriate to declare a method in the service interface and put the logic for those operations in the services themselves.
Sometimes, on the other hand, it's code which the service itself ought not to know about - at which point life becomes distinctly uglier :( Sometimes this sort of thing is really hard to avoid. I've occasionally found that a mixture of generics and lambda expressions help, e.g.
ConditionallyExecute<Service1>(service, s1 => s1.CallSomeService1Method());
ConditionallyExecute<Service2>(service, s2 => s2.CallSomeService2Method());
...
where ConditionallyExecute is something like:
private void ConditionallyExecute<T>(object obj, Action<T> action)
where T : class
{
T t = obj as T;
if (t != null)
{
action(t);
}
}
... but I'm not really happy when I do that :(
I like using a dictionary in these scenarios.
Dictionary<Type,Action<IService>>
What I believe you want is:
class ServiceFactory
{
Dictionary<Type, NewService> serviceCreators;
ServiceFactory()
{
serviceCreators = new Dictionary<Type, NewService>();
serviceCreators.Add(typeof(Task1), delegate { return new SomeService(); });
serviceCreators.Add(typeof(Task2), delegate { return new SomeOtherService(); });
}
public IService CreateService(IServiceTask messageObj)
{
if(serviceCreators.Contains(messageObj.GetType())
{
return serviceCreators[messageObj.GetType()];
}
return new DefaultService();
}
}
delegate IService NewService();
Or maybe to add a new method to IServiceTask - CreateService.
As for me - I would really go with doSomething() method on the Interface so that you could implement it in all these classes. You would have:
public void DoSomething(IService service)
{
service.doSomething();
}
This doesn't make it any better reading, but maybe better performing (if a service can't be two types at the same time):
public void DoSomething(IService service)
{
if (service is Service1)
{
//DO something
}
else if (service is Service2)
{
//DO something else
}
}
Another approach
Maybe this would be also a possible solution:
private Dictionary<Type, Action<object>> _TypeExecutor;
private void SetupExecutors()
{
_TypeExecutor = new Dictionary<Type, Action<object>>();
_TypeExecutor.Add(typeof(Service1), new Action<object>((target) => target.DoSomething()));
_TypeExecutor.Add(typeof(Service2), new Action<object>((target) =>
{
var instance = (Service2)target;
var result = instance.DoSomething();
}));
_TypeExecutor.Add(typeof(Service3), AnotherMethod);
}
private void AnotherMethod(object target)
{
var instance = (Service3)target;
var result = instance.DoSomething();
}
private void DoWork(ISomething something)
{
Action<object> action;
if (_TypeExecutor.TryGetValue(something.GetType(), out action))
{
action(something);
}
}
Generally speaking, if you think you must do something like in your code, this is a strong sign that there is something wrong with your design. If you pass an IService interface to the method, then the intention should ideally be that it wants to call a method on that interface - without caring what implementation is behind!
But apart from that. it might be useful in your case to have some sort of Servicetype property on your IService interface (ideally this would return an enum value), which you could then check with a switch statement. This of course wouldn't reduce the necessary number of logical branches (you won't be able to reduce it without refactoring your architecture), but at least this would significantly reduce the necessary amount of code.
Thomas
If the functionality does not rightly belong in IService then either Wills Command pattern and a Map of some type or by using the visitor pattern.
The latter requires you to add a new method IService.Visit and create interface IServiceVisitor with the methods Visit(Service1) and Visit(Service2) (etc).
Example:
interface IService
{
void Visit(IServiceVisitor visitor);
}
class Service1 : IService
{
void Visit(IServiceVisitor visitor)
{
visitor.Visit(this);
}
}
class Service2 : IService
{
void Visit(IServiceVisitor visitor)
{
visitor.Visit(this);
}
}
interface IServiceVisitor
{
void Visit(Service1 service);
void Visit(Service2 service);
}
class ClassThatDoesStuff : IServiceVisitor
{
{
void Visit(Service1 service)
{
// Service one code
}
void Visit(Service2 service)
{
// Service two code
}
public void DoSomething(IService service)
{
serivce.Visit(this);
}
}
use polymorphism, it's a very simple solution.
class Abstract
{
function something();
}
class A inherit Abstract
{
override something()
}
class B inherit Abstract
{
override something()
}
function foo (Abstract input)
{
input->something()
}
Assuming you want to execute certain method according to the actual type, you can use GetMethod on the instance, and if the method exists invoke it.
public void DoSomething(IService service)
{
System.Reflection.MethodInfo method = service.GetType().GetMethod("MySpecialMethod");
if (method != null)
method.Invoke(service, null);
}
This way you won't have to check the type at all, just check if the method exists - kind of walking around the tree, so I hope this approach is useful.
You can also use array of possible methods and iterating over them, checking each and have more elegant code this way.
Like others have said, the easiest solution would be for this logic to be done inside of your IService implementations themselves through an added method.
If this functionality really does not belong inside of IService though, the Visitor pattern would a much better solution than a large number of instanceof checks.
You would create an interface like
public interface IServiceHandler {
void handleService1(Service1 s);
void handleService2(Service2 s);
// add more methods for every existing subclass of IService
}
With an implementation that handles the logic currently inside of DoSomething, but with every branch separated into it's own method:
public class ServiceHandler : IServiceHandler {
public void handleService1(Service1 s) { ... }
public void handleService2(Service2 s) { ... }
}
IService would then need one addition method:
void accept(IServiceHandler sh);
which would be implemented in the specific implementations like
public class Service1 : IService {
...
public void accept(IServiceHandler sh) { sh.handleService1(this); }
....
}
and analogous for the other implementations.
Your original DoSomething() method can then be rewritten as
public void DoSomething(IService service) {
service.accept(new ServiceHandler());
}
The advantage of this approach is that your logic will be much better segregated, as well as slightly more performant as it no longer uses any instanceof checks or casts.
Also, if you ever add a new implementation of IService, the compiler will force you to add the appropriate handler for it (as it needs to implement the accept() method, which can only be done by adding the appropriate case to IServiceHandler as well), whereas with a solution dependent on a number of type-checks, it would be easy to forget to add the appropriate extra case.
Last but not least, if you ever were to need any other types of handlers, you could do so without needing any further changes to IService; you would simply create a new IServiceHandler implementation with the new logic.
If you write the Service classes yourself, interfaces are the way to go. If Foo() should be called on the object if its either a Service1 or a Service2 then they should implement a common interface and you just check if its either one of the two and then run the relevant code.
If they classes cant be changed, however, then I think youre out of luck. 20+ completely different classes which should have 20+ completely different sets of logic applied to them must simply... be handled differently.
Or am I missing some C# magic here? Every time I see code like this I think of how Go implement interfaces.
Consider this example
The Interface
interface IBusinessRules
{
string Perform();
}
The Inheritors
class Client1BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 1 Performed";
}
}
class Client2BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 2 Performed";
}
}
class Client3BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 3 Performed";
}
}
The factory class
class BusinessRulesFactory
{
public IBusinessRules GetObject(int clientIdentityCode)
{
IBusinessRules objbase = null;
switch (clientIdentityCode)
{
case 1:
objbase = new Client1BusinessRules();
break;
case 2:
objbase = new Client2BusinessRules();
break;
case 3:
objbase = new Client3BusinessRules();
break;
default:
throw new Exception("Unknown Object");
}
return objbase;
}
}
sample usage:
class Program
{
static void Main(string[] args)
{
BusinessRulesFactory objfactory = new BusinessRulesFactory ();
IBusinessRulesFactory objBase = objfactory.GetObject(2);
Console.WriteLine(objBase.Perform());
objBase = objfactory.GetObject(3);
Console.WriteLine(objBase.Perform());
Console.Read();
}
}
My question is, how about I add another method on the ALgorithm1 Class
but not in the interface because im going to just use it on special scenario?
class Client1BusinessRules: IBusinessRules
{
public string Perform()
{
return "Client1 Business rules is Performed";
}
public string Calculate()
{
return "Additional functionality for CLient1";
}
}
how Am I suppose to call that on the UI something like this
objBase = objfactory.GetObject(1);
Console.WriteLine(objBase.Calculate());
Is there any other solution? thanks in advance
EDIT: I rewrite it to resemble my current project design
I presume you are using the factory class in order to:
have a standard facade accepting parameters that lead to business rule selection and provisioning
encapsulate business rule provisioning
decouple the users from actual implementations of IBusinessRules
Hence I would solve your problem by introducing new interface
interface IComputableRules : IBusinessRules
{
string Calculate();
}
As long as you follow the interface-based design, there's nothing wrong about casting the actual instance to an interface different from IBusinessRules.
IBusinessRules businessRule = objFactory.GetObject(...some input...)
...
// check if the computable service is supported and print the result
IComputableRules computable = businessRule as IComputableRules;
if (computable)
{
Console.WriteLine(computable.Calculate());
}
Here you can think of you business rule classes as service providers, that guarantee some basic service, plus optional additional services depending on the nature of the business rule.
Note: By turning the BusinessRulesFactory into a generic class you might make the indication of a specific service a part of the factory contract, and make sure the returned business rule implementation will support a particular (otherwise optional) service.
class BusinessRulesFactory<TService> where TService : IBusinessRules
{
public TService GetObject(int clientIdentityCode)
{
// ... choose business rule in respect to both clientIdentityCode and TService
}
}
In case where you wouldn't require a specific additional service to be available, you'd just use IBusinessRules as the actual type parameter.
The whole point of the factory pattern is to return the proper implementation of a contract so that the consumer shouldn't worry about how to instantiate it but simply invoke its methods. You could always test the actual type, cast to it and invoke the method but that's a very bad design and I wouldn't recommend it. The consumer shouldn't know anything about the actual type. You will need to rethink your design.
If you want to stick to the current architecture you can introduce a new interface declaration
interface ICalculationRules
{
string Calculate();
}
Now let modify Client1BusinessRules by adding the interface declaration:
class Client1BusinessRules: IBusinessRules, ICalculationRules
{
// everything remains the same
}
Modify your calling code like this:
var objBase = objfactory.GetObject(1);
Console.WriteLine(objBase.Calculate());
var calcBase = obj as ICalculationRules;
if (calcBase != null) calculable.Calculate();
Maintenance implication: Every time you introduce a new interface, you have to touch all your calling code. Since you posted that this code is placed in the UI code, this can get quite a mess.
Each interface you are introducing just means added behaviour to a class. If you have a large range of different behaviours, then the solution above my not feel right, because there is always the need to use the as operation and conditional execution a method. If you want to stick to some classic design pattern this variability of behaviour can be countered with the Decorator Pattern or the Strategy Pattern. They can be smoothly combined with the Factory Pattern.
There are many approaches that can be employed in this case, and it depends on the cost you're willing to put in order to get the value.
For example, you can go with simple casting. You'll get the algorithm object from the factory, cast it to the proper (specific) algorithm object, and then call the "Calculate" function.
Another option - a much more generic one, that would also require much more code - would be to supply a querying mechanism within the base class, that will supply information about the available functionality within the object. This is somewhat comparable to querying for interfaces in COM.
The important questions you need to ask yourself is:
1. How many times will you need to implement specific functionality?
2. Is there a way you can solve the problem with added polymorphism stemming from the base class?
3. Will users of the derived objects know that they are using the specific object, or do you want them to be ignorant of the actual type?
In general what I personally do in such cases is start with the simplest solution (in this case, specific casting and calling the function), and go back and refactor as I go, when I have some more data about the domain. If you're sensitive to "smelly code", you'll get to a point where you see there's too much clutter and you'll refactor it into a better solution.
I would modify it like this
interface IBusinessRules
{
string Perform();
bool CanCalculate { get; }
string Calculate();
}
and add an abstract base class (optional but recommended for further extensibility)
public abstract class BusinessRules : IBusinessRules {
protected BusinessRules() {
}
protected virtual bool CanCalculateCore() {
return false; // Cannot calculate by default
}
protected virtual string CalculateCore() {
throw new NotImplementedException("Cannot calculate");
}
protected abstract string PerformCore();
#region IBusinessRules Members
public string Perform()
{
return PerformCore();
}
public bool CanCalculate
{
get { return CanCalculateCore(); }
}
public string Calculate()
{
return CalculateCore();
}
#endregion
}
So the call site now looks neat:
objBase = objfactory.GetObject(1);
if (objBase.CanCalculate) {
Console.WriteLine(objBase.Calculate());
}
One big problem of extending the interface is, it gives the caller no hint at all that you might support that interface as well.
This is a domain modelling issue and relates to what you mean by BusinessRule and IBase in your problem domain.
What is IBase? Sounds like it should be called IBusinessRule. In which case, what does Calculate mean in the context of a "business rule". If it has a generic meaning in your domain then IBusinessRule should implement it, as should the other classes, even if only as an empty method.
If it doesn't have generic meaning in your domain then your class should implement another interface ICalculable (IAlgorithm?) that has Calculate, which you call as:
ICalculable calculable = obj as ICalculable;
if ( calculable != null ) calculable.Calculate();