Is it correct to control how the service works from the caller of this service? I had such a problem today, and don't know if my solution is good or not. Hope someone more advanced can give me a feedback. Here is my problem:
I have got a service with method Foo:
public class Service
{
public int? Foo(int? number, bool throwException)
{
int? result = number;
if (result == null)
{
var result = ...
if (result == null && throwException)
{
throw new Exception("ZZZZ");
}
}
return result
}
}
Now in Caller class I got 2 methods where I invoke this Service:
public class Caller
{
public void Test1()
{
...
Service.Foo(number, TRUE);
...
}
public void Test2()
{
...
Service.Foo(number, FALSE);
...
}
As you can see for Test1 im sending flag throwException TRUE, and for Test2 FALSE, is it good practice to control how the Service's flow go from the Caller's methods?
That's what i tried to avoid:
public class Caller
{
public void Test1()
{
var a = Service.Foo1();
if (a == something)
{
throw ARgumentException("ZZZ");
}
var b = Service.Foo2();
if (b == something2)
{
throw ArgumentException("ZZZ2");
}
...
}
}
It is not recommended by the Clean Code book to use "flag" (boolean) arguments. In this case you should make two methods in the service, one FooRequired() and one FooOrDefault(), or something like that.
Related
I'm trying to make a method, MethodA, only accessible when bool, executable, is true. Otherwise an other method, MethodB, is accessible. For example:
private bool executable = true;
public int MethodA(); <-- // Is accessible from outside of the class because executable is true
public string MethodB() <-- // Is not accessible because executable is true
The main reason I'm trying to do this is because the 2 methods return 2 different types. So my question is, is this even possible?
Option #1
You may be able to get what you want using Polymorphism and Generics. This would also allow you to add additional method strategies if needed.
public interface IMethodStrategy<out T>
{
T DoSomething();
}
public class MethodOneStrategy : IMethodStrategy<string>
{
public string DoSomething()
{
return "This strategy returns a string";
}
}
public class MethodTwoStrategy : IMethodStrategy<int>
{
public int DoSomething()
{
return 100; // this strategy returns an int
}
}
// And you would use it like so...
static void Main(string[] args)
{
bool executable = true;
object result = null;
if (executable)
{
MethodOneStrategy methodA = new MethodOneStrategy();
result = methodA.DoSomething();
}
else
{
MethodTwoStrategy methodB = new MethodTwoStrategy();
result = methodB.DoSomething();
}
}
Option #2
Another option could be a simple proxy method to wrap the worker methods.
// proxy class to wrap actual method call with proxy call
public class MethodProxy
{
public object DoMethodWork(bool executable)
{
if (executable)
{
return MethodA();
}
else
{
return MethodB();
}
}
private int MethodA()
{
return 100; // returns int type
}
private string MethodB()
{
return "this method returns a string";
}
}
// used like so
static void Main(string[] args)
{
var methodProxy = new MethodProxy();
object result = methodProxy.DoMethodWork(true);
}
Use conditional compilation for this.
#if RELEASE
public string MethodB() ...
#endif
Although I have my doubts about whether you need this or not. Your rationale doesn't make much sense.
You can use different Build Configurations to manage your conditional compile symbols.
if(executable)
MethodA();
else
MethodB();
OR
if(executable)
MethodA();
MethodB();
not entirely sure what you are trying to do but this could be one way, probably not the most efficient way but could work depending on what you are trying to do?
public int MethodA(executable)
{
if(executable = true)
{
//do stuff
}
else
{
return -1;
}
}
public String MethodB(executable)
{
if(executable = false)
{
//do stuff
}
else
{
String error = "MethodB cannot be used right now";
return error;
}
}
I'm developing a simple service locator in C# using TDD.
At the moment, I've created a TryAddService method that looks like this:
public bool TryAddService(Type type, object service)
{
if (service == null)
{
return false;
}
if (this.services.ContainsKey(type))
{
return false;
}
if (!type.IsAssignableFrom(service.GetType()))
{
return false;
}
this.services.Add(type, service);
return true;
}
My question is, should I be returning false in all these cases? Or should I throw an exception?
My customers in this scenario would be other developers.
As informally agreed, whenever you use TryXXXX pattern, your method must be always successful, but return actual success result as boolean. If you'd like to throw and Exception, then just remove the "try" word from your method name.
On the top, if you follow the TryXXXX pattern, I recommend you to add a try-catch block, to ensure your method really always succeeds:
public bool TryAddService(Type type, object service)
{
if (service == null)
{
return false;
}
if (this.services.ContainsKey(type))
{
return false;
}
if (!type.IsAssignableFrom(service.GetType()))
{
return false;
}
try
{
this.services.Add(type, service);
}
catch
{
return false;
}
return true;
}
I use this scenario :
I have a class that all services return this class named (MyReturn for example)
public sealed class MyReturn<TEntity> : IDisposable
{
public string Message { get; set; }
public TEntity Entity { get; set; }
public string SysException { get; set; }
// and etc...
public void Dispose() {}
}
Now your service:
public MyReturn <bool> TryAddService(Type type, object service)
{
if (service == null)
return new MyReturn <bool> {Message = "Your messgage"};
//and etc...
return new MyReturn <bool>();
}
In your form u check Message , if null or empty, you have no error ....
You can customize it...
My customers in this scenario would be other developers.
Are you expecting consumers of your class will register types conditionally?
if (TryAddService(typeof(IService), new Service1()))
{
// Added successfully - what to do next
}
else
{
// What here? Try another service?
}
Or developers will just register implementation they need and rely on the fact that TryAddService will throw an exception during application startup.
TryAddService(typeof(IService), new Service1());
As developer I want to receive quickest feedback as possible if I did something wrong. Throwing exception during application startup (where usually service registration is done) will be quickest possible feedback. Unless you will use generics with constraints, which will provide feedback early during compile time.
If developers don't have logic for failed registration, then return nothing, but throw custom exception with descriptive message
public void TryAddService(Type type, object service)
{
if (service == null)
{
throw new RegisterServiceException($"Can not register null for type '{type.FullName}'");
}
if (this.services.ContainsKey(type))
{
throw new RegisterServiceException($"Service for type '{type.FullName}' already registerd.");
}
if (!type.IsAssignableFrom(service.GetType()))
{
throw new RegisterServiceException($"Type '{type.FullName}' should be assignable from service of type '{service.GetType().FullName}'");
}
this.services.Add(type, service);
}
I am trying to find the cleanest solution for returning value or error message from function / method in c#.
For now I have tried:
public float ValidateValue (float value)
{
if (value == VALID_VALUE)
{
return value;
}
else
{
throw new ArgumentException("Invalid value", "value");
}
}
This solution seems to be good enough but in Clean Code Cheap Sheet I have found:
Using Exceptions for Control Flow – Don't do this
Using exceptions for control flow:
has bad performance, is hard to understand and results in very hard
handling of real exceptional cases.
What will you do in the case of invalid input?
If you are writing code at the UI level that is taking the input from the user then it makes most sense to do something like:
private bool IsValid(float value)
{
return value == VALID_VALUE; // replace with real check.
}
Then in the calling code you would have:
public void ReactToInput()
{
float value = HoweverYouGetTheFloatFromTheUser();
if(!IsValid)
{
//Code to display error message.
}
else
{
//Code to do something useful.
//
//Code to display result.
}
}
Because your job at this level is "take what the user gave me, return what they want as best I can" and at this level its best to have the possibility of the user doing something incorrect front and centre.
If you are writing code for other code to make use of, then it makes most sense to do something like:
private void CheckValid(float valid)
{
if(value != VALID_VALUE) // replace with real check.
throw new ArgumentException();
}
Then in the calling code you would have:
public float DoWork(float value)
{
CheckValid(value)
//Code to do something useful.
//
//Code to return result.
}
Here your job is to do what the method's task is cleanly and return a meaninful result (or void if there isn't one). If you can't do that job, because the input you were given is nonsense (or for any other reason) then you need to stop as soon as you can and deal with that problem. You could do this by returning an error/success code every time and having calling code checking it every time, but while this approach does indeed have some advantages, exceptions let us:
Write with a focus on the correct behaviour.
Pass up exceptions.
For an example of 1, compare:
private bool WithExceptions()
{
return A() > B() && C() > D();
}
private bool WithExplicitChecks(out bool result)
{
result = false;
int a;
int b;
if(!A(out a))
return false;
if(!B(out b))
return false;
if(a <= b)
return true;
int c;
int d;
if(!C(out c))
return false;
if(!D(out d))
return false;
result = c > d;
return true;
}
For an example of 2, consider:
private void A()
{
if(_someField == null)
throw new InvalidOperationException("field not ready");
_someField.DoSomething();
}
private void B()
{
A();
}
private void C()
{
B();
}
private string D()
{
try
{
C();
}
catch(InvalidOperationException)
{
Console.Error.WriteLine("Was not ready");
}
}
Obviously a real case would have B() and C() do more, but we can see here that only A() has to worry about raising exceptions and only D() about dealing with them, B() and C() can both just concentrate on the main concern.*
The two approaches can be mixed. Consider:
private static string CheckValid(string path)
{
if(path.Length == 0)
return "You cannot enter an empty file path";
switch(path[path.Length - 1])
{
case '\\':
case '/':
return "You cannot enter a directory path";
}
return null;
}
public static void Main(string[] args)
{
Console.WriteLine("Enter a file path");
var path = Console.ReadLine().Trim();
var validationError = CheckValid(path);
if(validationError != null)
Console.Error.WriteLine(validationError);
else
{
try
{
using(var reader = new StreamReader(path))
Console.WriteLine(reader.ReadToEnd());
}
catch(FileNotFoundException)
{
Console.Error.WriteLine("File not found");
}
catch(UnauthorizedAccessException)
{
Console.Error.WriteLine("Access denied");
}
catch(IOException ioe)
{
Console.Error.WriteLine(string.Format("I/O Exception: {0}", ioe.Message));
}
}
Console.Read();
}
This simple program takes a file path from the user, and opens the relevant file and outputs the contents as text. It takes both approaches to error-handling.
Because we can easily check for invalid input that is empty, or which ends with / or \, that is done with simple control-flow and we present an error message instead of doing something.
Other issues we can only know about by trying to open the file and failing, so in those cases we handle the exceptions. I combine both explicit checks for two types of problem along with one for a general class of problems, and act accordingly.
There is a third type of exception handling here; if an exception happens that I don't expect at all, the program fails with a exception message being dumped for debugging purposes. This is the case anywhere you don't catch all exceptions, but a very useful one; because I don't have a blanket catch or catch(Exception) I don't confuse exceptions I'm expecting to deal with (go me for handling them!) with exceptions that are there because I made a mistake in not realising they could happen (boo me! now I have to fix it).
This is a simple program that takes a file path from the user, and outputs the contents of the file. Note that it combines both approaches:
*Do though always consider that something started in a method may not be finished if an exception busts through it.
If you want to validate some input value, I would expect a bool to be returned indicating 'valid' or 'invalid', or no return value and an exception thrown when the value is invalid.
So I would suggest to use this:
public bool ValidateValue(float value)
{
return value == VALID_VALUE;
}
Or this:
public void ValidateValue(float value)
{
if (value != VALID_VALUE)
{
throw new ArgumentException("Invalid value", "value");
}
}
So throwing an exception is not a problem, especially when there are multiple reasons to reject, and you want to distinguish the various reasons. Otherwise, just use a bool, like int.TryParse does for example.
A tuple may be useful to solve that issue:
public Tuple<float,string> ValidateValue (float value)
if (value == VALID_VALUE)
{
return new Tuple<bool, string>(value,string.Empty);
}
else
{
return new Tuple<bool, string>(false,"Invalid value");
}
When calling a function, check if the error string is empty first:
var validation = ValidateValue(myFloatValue);
if (validation.Item2 != string.Empty)
{
// report error
}
else
{
// No error core here validation.Item1 is your result
}
One idea could be to have some generic model. You may have some model roughly like:
public class MyReturnModel
{
public bool Success { get; set; }
public string ErrorOrSuccessMessage { get; set; }
public dynamic AnyModelToReturn { get; set; }
}
Now let's apply this on your provided case:
public MyReturnModel ValidateValue(float value)
{
//function logic here
bool result = value == VALID_VALUE;
string msg = result ? "valud is valid" : "value is invalid";
return new MyReturnModel { Success = result, ErrorOrSuccessMessage = msg }
}
I'm working on a framework in C# that will depend on pluggable components implemented as classes inheriting a base class. In order to make the components as simple as possible, I am working on some weird control flow.
The base class includes a static method RunStep(parameter). This method is called a number of times by the inheriting class, and each time it is called a condition is checked. If this condition happens to be false, I want the calling method to stop and return. A simplified working version of the code would be:
Base class:
class MyBase
{
private static object RunStep(string parameter)
{
if(SomeFunction(parameter))
return SomeOtherFunction(parameter);
else
return null;
}
}
Inheriting class:
class MyInheritor
{
public void Run()
{
object result = RunStep("mystring1");
if(null != result)
{
//perform some logic on result
result = RunStep("mystring2");
if(null != result){
//perform some different logic on result
RunStep("mystring3");
}
}
}
}
What I am wondering is whether it is possible to do something in the base class so that I can simplify the inheriting class to this:
class MyInheritor2
{
public void Run()
{
object result = RunStep("mystring1");
//perform some logic on result
result = RunStep("mystring2");
//perform some different logic on result
result = RunStep("mystring3");
}
}
}
I would put the parameters in a list and loop over them, but there is logic that needs to happen after each call to the RunStep method, and the logic is different each time. This takes a loop off the table. Also note that the logic between the RunStep calls accesses properties on result, so it crashes without the null checks.
It may seem like a trivial thing, but there may be thousands of these Inheriting classes and simplifying them is a big deal.
Let the base class to control the execution flow:
class Base
{
private readonly List<Tuple<string, Action>> steps = new List<Tuple<string, Action>>();
protected void RegisterStep(string parameter, Action someLogic)
{
steps.Add(Tuple.Create(parameter, someLogic));
}
protected void Run()
{
foreach (var step in steps)
{
var result = RunStep(step.Item1);
if (result == null)
{
break;
}
// perform some logic
step.Item2();
}
}
private object RunStep(string parameter)
{
// some implementation
return null;
}
}
class Derived : Base
{
public Derived()
{
RegisterStep("1", () => { });
RegisterStep("2", () => { });
RegisterStep("3", () => { });
// etc
}
}
There's no way to make a function call exit the calling function except for throwing an Exception, which you shouldn't do.
What you can do to make your code cleaner is to invert the cases.
object result = RunStep("mystring1");
if (result == null) return;
result = RunStep("mystring2");
if (result == null) return;
result = RunStep("mystring3");
if (result == null) return;
Having 2 different interfaces is a must.
How would you refactor this?
Should I refactor this code at all?
private void CreateInstanceForProviderA()
{
a = FactorySingleton.Instance.CreateInstanceA("A");
if (a == null)
{
ShowProviderNotInstanciatedMessage();
return;
}
a.Owner = Handle.ToInt32();
lbl_Text.Text = a.Version();
}
private void CreateInstanceForProviderB()
{
b = FactorySingleton.Instance.CreateInstanceB("B");
if (b == null)
{
ShowProviderNotInstanciatedMessage();
return;
}
b.Owner = Handle.ToInt32();
lbl_Text.Text = b.Version();
}
If there would be a common interface, I could write:
private void CreateInstanceForProvider(string provider)
{
p = FactorySingleton.Instance.CreateInstanceB(provider);
// p is shared over the whole class
if (p == null)
{
ShowProviderNotInstanciatedMessage();
return;
}
var tmpProvider = p as ICommonProvider;
tmpProvider .Owner = Handle.ToInt32();
lbl_Text.Text = tmpProvider .Version();
}
Well, the first thing to do is to yell at the author of FactorySingleton to fix has damn code so that ClassA and ClassB have a common interface for their common fields.
In the meantime, you pretty much stuck using reflection, which would be ugly and not worth it for just that little bit.
What version of C# are you using?
In C# 4 (Visual Studio 2010) the new dynamic keyword could help share code in this case. I wouldn't use if it this is a performance-critical section of code though, but if this just runs a handful of times then go ahead.
InstanceA and InstanceB ought to implement a common interface.
public interface IA : ICommon {...}
public interface IB : ICommon {...}
public interface ICommon
{
int Owner {get;}
string Version();
}
This way, you still have two different interfaces, but the common aspects of those interfaces are defined in a way that you can do some of the same things with both of them.
Perhaps have a third method that is private, and replace your code with calls to this third method, as so:
private void CreateInstanceForProviderA()
{
return DoSomething();
}
private void CreateInstanceForProviderB()
{
return DoSomething();
}
public interface ICommon
{
int Owner { get; }
string Version();
}
public interface IA : ICommon
public interface IB : ICommon
private void CreateInstanceForProvider(ICommon c)
{
if (c == null)
{
ShowProviderNotInstanciatedMessage();
return;
}
c.Owner = Handle.ToInt32();
lbl_Text.Text = c.Version();
}
It's always painful to fight the type system. Without using dynamic, here goes my attempt.
Given that you have these two distinct interfaces for a and b:
interface IA {
int Owner { set; }
string Version();
}
interface IB {
int Owner { set; }
string Version();
}
You can create a wrapper type like this:
class WrapperAB : IA, IB {
IA a; IB b;
public WrapperAB(object o) {
if (o is IA) a = (IA)o;
else if (o is IB) b = (IB)o;
else throw new Exception();
}
public int Owner {
set {
if (a != null) a.Owner = value;
else b.Owner = value;
}
}
public string Version() {
if (a != null) return a.Version();
else return b.Version();
}
}
And change your methods to this:
private void CreateInstanceForProviderA() {
CreateInstanceForProvider<IA>("A", FactorySingleton.Instance.CreateInstanceA, out a);
}
private void CreateInstanceForProviderB() {
CreateInstanceForProvider<IB>("B", FactorySingleton.Instance.CreateInstanceB, out b);
}
private void CreateInstanceForProvider<TI>(string name, Func<string, TI> factory, out TI instance) {
instance = factory(name);
if (instance == null) {
ShowProviderNotInstanciatedMessage();
return;
}
var w = new WrapperAB(instance);
w.Owner = Handle.ToInt32();
lbl_Text.Text = w.Version();
}
I would leave it as it is, no refactoring necessary...
YET!
If/when ProviderC shows up, then I would refactor. 8 )
It all depends on those method calls (.CreateInstanceA and .CreateInstanceB).
If they're doing the same things in the same way, and the only difference is that string parameter, then yes: refactor the method to CreateInstanceForProvider(string providerCode) and let the user / calling code pass in the proper parameter.
If they do slightly different things, then you may still be able to refactor, and it becomes more of a headache. At that point, you have to determine whether the increased abstraction (and additional ease of adding new Providers) is worth refactoring and having to re-run (and possibly rewrite) whatever tests are necessary.
Remove the duplicate code. In this case, you should be able to remove the middle message block that does the null check and message for a failed instantiation.
private void CreateInstanceForProviderA()
{
a = FactorySingleton.Instance.CreateInstanceA("A");
if (IsNullObject(a))
{
return;
}
a.Owner = Handle.ToInt32();
lbl_Text.Text = a.Version();
}
private void CreateInstanceForProviderB()
{
b = FactorySingleton.Instance.CreateInstanceB("B");
if (IsNullObject(b))
{
return;
}
b.Owner = Handle.ToInt32();
lbl_Text.Text = b.Version();
}
private bool IsNullObject(object obj)
{
if (obj == null)
{
ShowProviderNotInstanciatedMessage();
return true;
}
return false;
}
If you do find a way to provide a common interface or shared virtual methods on these providers, we can refactor more aggressively.
I'd pass an enum in to specify the create instance code to call. After that create a wrapper class containing methods to get/set using reflection as suggested in other answers use reflection. Not sure it's worth it, as you code is probably harder to read than before.
public enum Provider
{
A,
B
}
private void CreateInstanceForProvider(Provider provider)
{
ProviderWrapper provider = null;
switch (provider)
{
case Provider.A:
provider = new ProviderWrapper(FactorySingleton.Instance.CreateInstanceA("A"));
break;
case Provider.B:
provider = new ProviderWrapper(FactorySingleton.Instance.CreateInstanceB("B"));
break;
}
if (provider == null)
{
ShowProviderNotInstanciatedMessage();
return;
}
provider.SetOwner(Handle.ToInt32());
lbl_Text.Text = provider.GetVersion();
}
public class ProviderWrapper
{
private readonly object _original;
public ProviderWrapper(object original)
{
_original = original;
}
public void SetOwner(int value)
{
_original.GetType().GetProperty("Owner").SetValue(_original, value, null);
}
public string GetVersion()
{
return (String)_original.GetType().GetProperty("Owner").GetValue(_original, null);
}
}
EDIT: This does no work because a and b are different types (not sure if that was before or after I gave my answer...)
I'm assuming a and b are fields, not properties.
Abstractly, put the common functionality in a single method called by both of the original methods:
private void CreateInstanceForProviderA()
{
a = CreateInstanceForProvider("A");
}
private void CreateInstanceForProviderB()
{
b = CreateInstanceForProvider("B");
}
private FactorySingleton CreateInstanceForProvider(string which)
{
var instance = FactorySingleton.Instance.CreateInstanceB(which);
if (instance == null)
{
ShowProviderNotInstanciatedMessage();
return;
}
instance.Owner = Handle.ToInt32();
lbl_Text.Text = instance.Version();
return instance;
}