I am writing a method in c# class as shown below:
using(sftpClient)
{
sftpClient.Connect();
try{
//Do some process
}
catch(Exception ex)
{
}
sftpClient.Disconnect();
}
I need to create some more methods similar to the above but the logic changes only inside the try{} catch{} block. Can anyone suggest some best way to achieve this using some design pattern?
You could create an abstract base class:
abstract class MyBaseClass {
protected abstract void DoSomething();
public void DoSmtpStuff() {
smtpClient.Connect();
try {
DoSomething();
} catch (Exception ex) {
}
smtpClient.Disconnect();
}
}
and then just create inheritances of that class, which implement only the DoSomething method.
Take a look at the Strategy Pattern (emphasis my own):
In computer programming, the strategy pattern (also known as the
policy pattern) is a software design pattern that enables an
algorithm's behavior to be selected at runtime.
So basically, you would declare an interface, say, IBehaviour and define some method:
public interface IBehaviour
{
void Process();
}
Then have a different class implement IBehaviour for each piece of logic you want to have.
The class where you need to consume the logic would then allow passing an IBehaviour object and in your try block just do behaviour.Process().
This will allow you to set up the behaviour from outside the class and then simply pass it along to the class in which you want to actually do something with it.
Alternative to classes is just take Action as argument:
TResult WithSftpClient<TResult>(Func<TResult, SftpClient> operation)
{
TResult result = default(TResult);
// Note that one may need to re-create "client" here
// as it is disposed on every WithSftpClient call -
// make sure it is re-initialized in some way.
using(sftpClient)
{
sftpClient.Connect();
try
{
result = operation(sftpClient);
}
catch(Exception ex)
{
// log/retrhow exception as appropriate
}
// hack if given class does not close connection on Dispose
// for properly designed IDisposable class similar line not needed
sftpClient.Disconnect();
}
return result;
}
And use it:
var file = WithSftpClient(client => client.GetSomeFile("file.name"));
You can use this pattern:
abstract class ProcedureBase<T>
{
public T Work()
{
using(sftpClient)
{
sftpClient.Connect();
try{
ProtectedWork();
}
catch(Exception ex)
{
}
sftpClient.Disconnect();
}
}
protected abstract T ProtectedWork();
}
class Procedure1 : ProcedureBase<TypeToReturn>
{
protected override TypeToReturn ProtectedWork()
{
//Do something
}
}
class Procedure2 : ProcedureBase<AnotherTypeToReturn>
{
protected override AnotherTypeToReturn ProtectedWork()
{
//Do something
}
}
Usage:
static void Main(string[] args)
{
Procedure1 proc = new Procedure1();
proc.Work();
}
Related
I couldn't figure out how to formulate the title any better. I see quite a few posts with similar titles but which discuss entirely different stuff.
So here we go. The actual on-ground situation is complex, but I'll try to post an absolute minimalistic example to describe it.
Let's say we have a class named Animal:
class Animal
{
public void Run()
{
try
{
//try running
}
catch(Exception e)
{
MessageBox.Show(this.SomeCleverWayOfGettingPropertyName() + " failed to run");
}
}
}
Now I define several properties of Animal type in another class:
class Zoo
{
public Animal Zebra {get; set;}
public Animal Lion {get; set;}
public Animal Rhino {get; set;}
public void RunAll()
{
Zebra.Run();
Lion.Run();
Rhino.Run();
}
}
What do I write in place of SomeCleverWayOfGettingPropertyName() to let it show name of the animal (that is name of the declared property), like "Zebra failed to run".
As I said, the actual situation is more complex, so kindly avoid answers like, "why don't you redesign your entire code base and instead try X". My hope is to find something in System.Reflection to find out the calling member's name, but I haven't found anything like that yet.
Ideally you would rethink your problem, and possibly catch outside of the run
Depending on your exact needs, an expression might work.. However it really is a terrible solution, if you went to all the effort you might as well catch outside, or just pass the member name in.
Given
public class Animal
{
public void Run()
{
Console.WriteLine("Running");
}
}
public static class MemberInfoGetting
{
public static void Run<T>(this Expression<Func<T>> memberExpression) where T : Animal
{
var expressionBody = (MemberExpression)memberExpression.Body;
try
{
var animal = Expression.Lambda<Func<Animal>>(expressionBody).Compile()();
animal.Run();
throw new Exception("bob");
}
catch
{
Console.WriteLine($"{expressionBody.Member.Name} : failed to run");
}
}
}
Usage
public static Animal Rhino { get; set; } = new Animal();
public static void Main()
{
MemberInfoGetting.Run(() => Rhino);
}
Output
Running
Rhino : failed to run
This is basically not possible with this approach. What happens when you call Zebra.Run():
Runtime calls the auto-generated get_Zebra() method, putting the Zebra's Animal instance pointer on the stack.
Runtime calls the Animal.Run() instance method.
All variable/property info about where that instance came from is pretty much gone at that point.
Now Animal.Run() doesn't know it's being called on an instance that came from a property, and there's no guarantee it will be. It could as well be a local, a method parameter or a new()ed instance, one from a factory or a collection element. You'll have to pass this info yourself.
Alternatively, if it's for error handling, it may be easier than you think without having to resolve to compiler magic or expensive expression refactoring:
In your exception handler, log the relevant properties that identify the Animal instance. Combined with the stack trace, this should give you enough information.
you can try this:
class Animal
{
public void Run([CallerMemberName] string caller = null)
{
try
{
//try running
}
catch(Exception e)
{
MessageBox.Show(caller + " failed to run");
}
}
}
The only way to reasonable do this is change RunAll() such that it monitors each call, to the now modified run
class Animal
{
static readonly Random rng = new Random();
public bool Run()
{
if (rng.NextDouble() < 0.5)
{
return false;
}
return true;
}
}
class Zoo
{
...
public void RunAll()
{
try
{
if (!Zebra.Run())
{
throw new Exception(nameof(Zebra));
}
if (!Lion.Run())
{
throw new Exception(nameof(Lion));
}
if (!Rhino.Run())
{
throw new Exception(nameof(Rhino));
}
}
catch (Exception ex)
{
Debug.WriteLine($"{ex.Message} failed to run.");
}
}
}
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.
Suppose I have various arbitrary sections of code to run, but before each section, I have to run a Start() method and then after each section I need to run a Complete() method. However, if an exception is thrown in the code section, I want to run a Fail(string message) method instead of Complete(). Is there a design pattern that elegantly encapsulates this to make it neat and easily repeatable?
For example, let's say I have a type called Thing that contains a Start() method that adds a row to a logging db table to reflect that a task is in progress, a Complete() method that changes that row to reflect that the task finished and a Fail(string message) method that changes the row to reflect that the task failed. These are just examples though, they could be doing any set-up and tidy up type tasks.
The naive implementation might be simply to call those methods manually:
public void DoStuff()
{
var thing = new Thing();
thing.Start();
try
{
DoImportantStuff();
thing.Complete();
}
catch (Exception e)
{
thing.Fail(e.Message);
}
}
But if I'm going to have to repeat this in a lot of different places, it ends up creating quite a lot of duplication and it might be easy to forget to call Complete or mess this up in some subtle way.
In C#, there's the using pattern, which provides a good way of encapsulating most of this. For example, if my Thing type looked like this:
public class Thing : IDisposable
{
public Thing(){
Start();
}
private void Start() { /* start */ }
private void Complete() { /* complete */ }
public void Dispose()
{
Complete();
}
}
My DoStuff() method could now be simplified to this:
public void DoStuff()
{
using(new Thing())
{
DoImportantStuff();
}
}
Which is much nicer. But it doesn't allow me to call Fail instead of Complete if an exception is thrown because (I think!) the Dispose method is essentially called in a Finally block.
I have thought of having a try/catch inside the using block and then setting a thing.HasFailed flag inside the catch block and then using that in the Dispose method to decide whether to Complete or Fail. But that seems a bit fiddly and I'd like the consumer of Thing to have to do as little as possible to make it work correctly.
So is there a design pattern that encapsulates what I want to do and avoids the need to manually write a try\catch each time?
You could have a Thing like this:
public class Thing
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string message) {}
public void DoAction(Action action)
{
this.Start();
try
{
action();
this.Complete();
}
catch (Exception e)
{
this.Fail(e.Message);
}
}
}
And Use it like this:
Thing thing = new Thing();
thing.DoAction(this.DoStuff);
The pattern is called "template method". You can find your implementation under the title "aspect oriented programming".
(https://msdn.microsoft.com/en-us/library/aa288717(v=vs.71).aspx)
Using Delegates.
public class Thing : IDisposable
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string _szMessage) {/* fail */}
public delegate void ProcessClientStuff();
private ProcessClientStuff m_delegateClientStuff;
public Thing(ProcessClientStuff _delegateClientStuff) {m_delegateClientStuff = _delegateClientStuff}
public void Dostuff()
{
Start();
try
{
m_delegateClientStuff();
Complete();
}
catch(Exception e)
{
Fail(e.Message);
}
}
}
void ClientStuff()
{
Console.WriteLine("Hello");
}
Thing oClientStuffProcessor = new Thing(ClientStuff);
oClientStuffProcessor.Dostuff();
Can please someone explain, in a very easy/simple way, how to handle an exception via attributes?
For example if I have simple code like this:
class Test{
static void Main(string[] args){
try {
Console.WriteLine("div= "+ Division(0));
}
catch (DivideByZeroException e)
{
Console.WriteLine("Attempted divide by zero -->" + e.Message);
}
Console.ReadLine();
}
public static int Division(int i){ return 10 / i; }
}
How can I change this code using attributes?
This cannot be done with .NET out of the box.
tl;dr - There is no "very easy/simple way (...) to handle an exception via attributes"
You're trying to handle exceptions in a AOP way (aspect oriented programming), where you attach aspects to methods - using attributes, for example.
PostSharp allows you to do this:
Without postsharp:
public class OrderFulfillmentService
{
public void Fulfill( Order order )
{
try
{
// Do stuff.
}
catch ( Exception e )
{
if ( ExceptionHandler.Handle(e) )
throw;
}
}
}
With postsharp:
public class OrderFulfillmentService
{
[HandleException]
public void Fulfill( Order order )
{
// Do stuff.
}
}
Beware of the downsides of using AOP though: the code might become less readable (as it isn't written sequentially) and less maintainable.
Instead of using attributes, you could also use Castle Interceptor/DynamicProxy
You will need to create an interceptor that wraps around your object and intercepts calls to it. At runtime, Castle will make this interceptor either extend your concrete class or implement a common interface - this means you'll be able to inject the interceptor into any piece of code that targets the intercepted class. Your code would look something like this:
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try{
invocation.Proceed();
} catch(Exception ex) {
//add your "post execution" calls on the invocation's target
}
}
}
Introduction to AOP with Castle: http://docs.castleproject.org/Windsor.Introduction-to-AOP-With-Castle.ashx
I have a class which needs to behave differently when being called remotely via .Net remoting. How can I determine, inside the class, if this is the case?
class RemoteClass : MarshalByRefObject
{
public void SomeMethod ()
{
if (ConditionWhatINeed) //If this method was called internally/remotely
{
//Do one stuff
}
else
{
//Do another suff
}
}
you may want to have a look at the RemotingServices.IsObjectOutOfContext Method. it also has an example you may find useful. of course, because you'll be calling this method server-side on 'this' it will never be seen as a remoting object but if you add a parameter to your method than that parameter will be in local context if not remoting and out of context when remoting (PS this is an unverified assumption on my account). Another useful helper may be the RemotingServices.IsTransparentProxy Method.
There may be a way using one of the *Services objects under the System.Runtime.Remoting hierarchy, as mtijn indicated. However, you have deep problems in your object model. Having dual responsibility on objects is bad practice, difficult to maintain and difficult to understand. Why not rather expose a dedicated 'remote' object; the following sample demonstrates it:
class Program
{
static void Main(string[] args)
{
InitializeRemoting();
var remote = GetRemotingObject("localhost");
var local = new LocalClass();
remote.SomeMethod();
local.SomeMethod();
Console.ReadLine();
}
static void InitializeRemoting()
{
var c = new TcpServerChannel(9000);
ChannelServices.RegisterChannel(c, false);
WellKnownServiceTypeEntry entry = new WellKnownServiceTypeEntry
(
typeof(RemoteClass),
"LocalClass", // Lie about the object name.
WellKnownObjectMode.Singleton
);
RemotingConfiguration.RegisterWellKnownServiceType(entry);
}
static LocalClass GetRemotingObject(string serverName)
{
TcpClientChannel channel = new TcpClientChannel("tcp-client", new BinaryClientFormatterSinkProvider());
ChannelServices.RegisterChannel(channel, false);
return (LocalClass)Activator.GetObject
(
typeof(LocalClass), // Remoting will happily cast it to a type we have access to.
string.Format("tcp://{0}:9000/LocalClass", serverName)
);
}
}
public class LocalClass : MarshalByRefObject
{
public void SomeMethod()
{
OnSomeMethod();
}
protected virtual void OnSomeMethod()
{
// Method called locally.
Console.WriteLine("Local!");
}
}
// Note that we don't need to (and probably shouldn't) expose the remoting type publicly.
class RemoteClass : LocalClass
{
protected override void OnSomeMethod()
{
// Method called remotely.
Console.WriteLine("Remote!");
}
}
// Output:
// Remote!
// Local!
Edit: To answer your question directly, even though what you are trying to achieve is bad practice, duplicate my code and simply provide a virtual bool IsLocal { get { return true; } } on the local class and override it on the remote class. You can then use the property in your if statements.
Edit: If you server and your clients needs to share the exact same instance of the class you should use the Facade Pattern. For example:
class CommonImplementation
{
public static readonly CommonImplementation Instance = new CommonImplementation();
private CommonImplementation() { }
public void SomeMethod(string someArg, bool isServerCall)
{
if (isServerCall)
{
Console.WriteLine("Remote! {0}", someArg);
}
else
{
Console.WriteLine("Local! {0}", someArg);
}
}
}
// These two classes are the facade.
public class LocalClass : MarshalByRefObject
{
public virtual void SomeMethod(string someArg)
{
CommonImplementation.Instance.SomeMethod(someArg, false);
}
}
class RemoteClass : LocalClass
{
public override void SomeMethod(string someArg)
{
CommonImplementation.Instance.SomeMethod(someArg, true);
}
}