I've got a design question.
I've got a static class used in some old code that calls a static method to run some operation. If a certain condition is met, I want to call another method right after it.
I wanted to use the decorator pattern but I can't exactly return an instance of the static class if the condition is not met.
This is what's happening now.
var result = StaticClass.DoSomething(some parameters);
What I want is to write to a database right after that DoSomething is called if another variable is true and I didn't want to just pile on to the old code with conditionals so I'd rather delegate that to some other class. This is what I really want to do.
var result = StaticClassFactory(condition).DoSomething(some parameters);
Class1
void DoSomething(parameters) {
StaticClass.DoSomething()
}
Class2
void DoSomething(parameters) {
StaticClass.DoSomething();
DoSomethignElse();
}
Any suggestions?
What you can do is use an interface to represent the "doer":
public interface IDoer
{
void DoSomething(object parameters);
}
Then create the two classes:
public class DefaultDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
}
}
public class AugmentedDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
DoSomethingElse();
}
}
Then use a factory to return an instance that implements IDoer based on the condition:
public class DoerFactory
{
public IDoer GetDoer(object someCondition)
{
//Determine which instance to create and return it here
}
}
I used placeholders of type object for some things as no more information is available.
Related
I was wondering how I should decide to create an object, on method or class instance.Below a few examples to clarify. I want to the best approach to know how I should determine to choose between example 1 and 2.
IMPORTANT: Consider this a Windows Service (SVC) hosted in IIS.
Example 1
public class mySvcService
{
ReusableClass rClass = new ReusableClass();
public void MethodOne()
{
//Do Method One Stuff...
rClass.doSomething();
}
public void MethodTwo()
{
//Do Method Two Stuff...
rClass.doSomething();
}
}
public class ReusableClass
{
string valueOne;
string valueTwo;
string valueThree;
public void doSomething()
{
//DoSomeWork
}
}
Example 2
public class mySvcService
{
public void MethodOne()
{
ReusableClass rClass = new ReusableClass();
//Do Method One Stuff...
rClass.doSomething();
}
public void MethodTwo()
{
ReusableClass rClass = new ReusableClass();
//Do Method Two Stuff...
rClass.doSomething();
}
}
public class ReusableClass
{
string valueOne;
string valueTwo;
string valueThree;
public void doSomething()
{
//DoSomeWork
}
}
It is all about state. Will the object preserve some state between the two method calls, or even within the method, or not? If so, you should keep the object alive. Else, you can create a new object every time you call the method, or maybe even make the method static if there is never any state involved.
So:
Class preserves state that should be kept across methods: make a class variable or pass the object along the methods.
Class preserves state that should be kept within the same method: make a local variable.
Class doesn't preserve any state: make the method static, no instance needed.
The golden rule is to keep the scope as local as possible. From the second example if you are going to use doSomething() everywhere then it is better to create it once and have class level scope. If you need doSomething() only in one method, create the object locally within the method.
It is better to leave it inside of a method. Usually, it is being done inside of the constructor. This has the favor that it can incorporate a factory for different scenarios, or that it can be easily injected. I would strongly suggest to separate the responsibilities of the properties and let them be used as needed.
If you want to limit the scope of the object to a method, It can be done by using "Method injection" as shown below. You can use the other setter and constructor injection methods if the scope of the object is through out the class.
public interface IReusable
{
void doSomething();
}
public class Reusable: IReusable
{
public void doSomething()
{
//To Do: Some Stuff
}
}
public class mySvcService
{
private IReusable _reuse;
public void MethodOne(IReusable reuse)
{
this._reuse= reuse;
_reuse.doSomething();
}
public void MethodTwo(IReusable reuse)
{
this._reuse= reuse;
_reuse.doSomething();
}
}
Is there a way to modify the behavior of a static method at runtime?
for example:
Say I have this class
public class Utility {
public static void DoSomething(string data){
//...
}
}
Is there a way to do something like this:
typeof(Utility).SetMethod("DoSomething", (data) => { /*Do something else...*/ });
Such that if you call Utility.DoSomething it executes the new code?
What you want to do is pass the behavior you want as another parameter into the function.
public static void DoSomething(string data, Action<string> operation)
{
operation(data);
}
This is an oversimplified example, of course. What you actually wind up doing in your own code is going to depend on what operation actually does.
If you're trying to modify the behavior of an existing, compiled, in-production method, and cannot overload or override the method in the usual ways, the only way I know of to do that is CIL Rewriting, possibly using an Aspect Weaver.
Sure.
public class Utility {
public static Action<String> _DoSomething;
public static void DoSomething(string data){
if (_DoSomething != null) {
_DoSomething();
return;
}
// default behavior here.
}
}
And to mask the default behavior:
Utility._DoSomething = (data) => { /* do something else */ };
I don't see why you wouldn't just create a new class that inherits from Utility and define a new function that does what you want.
public class Program
{
static void Main(string[] args)
{
if (true)
{
Utility.DoSomething("TEST");
} else
{
Util1.DoSomething("TEST");
}
}
}
public class Utility
{
public static void DoSomething(string data)
{
//Perform some action
}
}
abstract class Util1 : Utility
{
public static new void DoSomething(string data)
{
//Perform a different action
}
}
I think although it is possible to do this you should ask yourself: "Why do I need this functionality"? Usually a method stays as is, and does what it is supposed to do according to its interface which is given by its name and signature. So while you can add additional logic by adding an Action<T>-parameter to your signature you should ask yourself if this won´t break the contract of the interface and therefor what the method was designed for.
Having said this you should consider either overwrite your method if the functionality you need is some kind of "making the same things differently then the parent-class" or extend it by adding a dependency into your consuming class and add some methods to that class that extent the functionality provided by the contained class (see also favour composition over inheritance)
class MyClass {
Utility MyUtility;
void ExtraMethod() { /* ... */ }
}
EDIT: As you´re using a static method the opportunity on overwriting is obsolete. However IMO that sounds like a great design-flaw.
I have a directory full of classes, and they basically all look like this:
class QEDestroy {
void showSettings() {
// Do Something Here
}
}
I then have a class that will instantiate one of the classes based on an item that the user selects:
public class QESettings {
public void GetSettings() {
if (QEActions.actionInt >= 0) {
string action = QEActions.actions[QEActions.actionInt];
// Generate the class based on the action.
// Run showSettings() within the class.
}
}
}
What I can't figure out is how to instantiate the class; for example QEDestroy. From what I have read this is how the class is created:
var myObj = Activator.CreateInstance("", "QE" + action);
If so, how do I run the method showSettings()?
The simplest solution is often the correct one. Create an interface.
public interface QE
{
void showSettings();
}
Then have different "versions" of QE that perform different tasks on the showSettings() function.
public class QE_Example
{
public void override showSettings()
{
print("I am different.");
}
}
Then when you instantiate in your QESettings class you do it like this:
public void GetSettings()
{
if(QEActions.actionInt >= 0)
{
...
QE q = new QE_Example();
q.showSettings();
}
}
This means you have actually stumbled upon a well known Design Pattern named Strategy Pattern.
I'm trying to write a wrapper for a Selenium test that re-runs the test if it fails, I've got the mechanics working fine. But I need to figure out a way of passing either a function/method or (preferably) multiple methods inside of the function. Here's an example of what I want to achieve:
In the wrapper class:
public class TestRunner{
public void RunTest(function FuncToRun){
FuncToRun();
}
}
In the test:
public class Tests{
public void Test(){
...Run test methods...
}
TestRunner.RunTest(Test());
}
This is purely for demonstration. I know that this doesn't work, but I hope it will convey my point to you.
Looks as though you need a delegate.
An applicable delegate for your scenario is the Action delegate which can be used to represent a single parameterless method.
public class TestRunner
{
public void RunTests(params Action[] tests)
{
foreach (var test in tests)
{
test.Invoke();
}
}
}
Note the use of the params keyword which will allow you ro supply any number of tests to the RunTests method. Here is an example using an implicit method group conversion:
public class Tests
{
public void TestOne() {
}
public void TestTwo() {
}
}
...
var runner = new TestRunner();
var tests = new Tests();
runner.RunTests(tests.TestOne, tests.TestTwo);
You could use Action parameters to do this
public class TestRunner{
public void RunTest(Action FuncToRun){
FuncToRun();
}
}
public class Tests{
public void Test(){
...Run test methods...
}
TestRunner.RunTest(() => Test());
}
You want to do something like this. But need more context as in inputs and what return value you are expecting.
Func<string, int> myMethodName
This is an example of usage:
public bool RunThisMethod(Func<string, int> myMethod)
{
//... do stuff
int i = myMethod("My String");
//... do more stuff
return true;
}
use delegate . simply declare a delegate to the method you want to pass and call and assign the method to it.
http://msdn.microsoft.com/en-IN/library/ms173171.aspx
You may use delegates or even Action or Func objects.
public class TestRunner{
public void RunTest(Action funcAction){
funcAction();
}
}
public class Tests{
public void Test(){}
TestRunner.RunTest(Test);
}
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.