All i have something i have been trying to do for a while and have yet to find a good strategy to do it, i am not sure C# can even support what i am trying to do.
Example imagine a template like this, repeated in manager code overarching cocept function Returns a result consisting of a success flag and error list.
public Result<Boolean> RemoveLocation(LocationKey key)
{
List<Error> errorList = new List<Error>();
Boolean result = null;
try{
result = locationDAO.RemoveLocation(key);
}catch(UpdateException ue){
//Error happened less pass this back to the user!
errorList = ue.ErrorList;
}
return new Result<Boolean>(result, errorList);
}
Looking to turn it into a template like the below where Do Something is some call (preferably not static) that returns a Boolean. I know i could do this in a stack sense, but i am really looking for a way to do it via object reference.
public Result<Boolean> RemoveLocation(LocationKey key)
{
var magic = locationDAO.RemoveLocation(key);
return ProtectedDAOCall(magic);
}
public Result<Boolean> CreateLocation(LocationKey key)
{
var magic = locationDAO.CreateLocation(key);
return ProtectedDAOCall(magic);
}
public Result<Boolean> ProtectedDAOCall(Func<..., bool> doS开发者_高级运维omething)
{
List<Error> errorList = new List<Error>();
Boolean result = null;
try{
result = doSomething();
}catch(UpdateException ue){
//Error happened less pass this back to the user!
errorList = ue.ErrorList;
}
return new Result<Boolean>(result, errorList);
}
If there is any more information you may need let me know.
I am interested to see what someone else can come up with.
Marc solution applied to the code above
public Result<Boolean> CreateLocation(LocationKey key)
{
LocationDAO locationDAO = new LocationDAO();
return WrapMethod(() => locationDAO.CreateLocation(key));
}
public Result<Boolean> RemoveLocation(LocationKey key)
{
LocationDAO locationDAO = new LocationDAO();
return WrapMethod(() => locationDAO.RemoveLocation(key));
}
static Result<T> WrapMethod<T>(Func<Result<T>> func)
{
try
{
return func();
}
catch (UpdateException ue)
{
return new Result<T>(default(T), ue.Errors);
}
}
Something like:
public Result<Boolean> RemoveLocation(LocationKey key)
{
return WrapMethod(() => locationDAO.RemoveLocation(key));
}
static Result<T> WrapMethod<T>(Func<T> func) {
try
{
return new Result<T>(func());
}
catch (SomeExceptionBase ex)
{
return new Result<T>(ex.ErrorList);
}
catch (Exception ex)
{
return new Result<T>((List<Error>)null);
}
}
and (minimum shown)
class Result<T>
{
private Result(bool isError, T value, List<Error> erors) { }
public Result(T value) : this(false, value, null){ }
public Result(List<Error> errors) : this(true, default(T), errors) { }
}
class SomeExceptionBase : Exception
{
public List<Error> ErrorList { get; private set; }
}
(although if I had to do this I'd probably do something more interesting with exceptions that don't happen to be SomeExceptionBase
)
We have the following in our project, it looks very similar
public TResult DoCall<TResult,TProvider>(Func<TProvider, TResult> action) where TProvider : class, IProvider
{
TResult ret = default(TResult);
try
{
var prov = (TProvider) ModelManagerProvider.GetProviderByType(typeof(TProvider));
ret = action(prov);
}
catch (Exception ex)
{
ThrowErrorTool.ThrowError(ex);
}
return ret;
}
and here is how we call it
public bool UpdateAdverseEventSection(AdverseEventsDTO aeDTO)
{
return DoCall((AdverseEventsProvider r) => r.UpdateAdverseEventSection(aeDTO));
}
static Result<T> WrapMethod<T>(Func<LocationDao, Result<T>> func)
{
try
{
var l = new LocationDao();
return func(l);
}
catch (UpdateException ue)
{
return new Result<T>(default(T), ue.Errors);
}
}
public Result<Boolean> RemoveLocation(LocationKey key)
{
return WrapMethod((l) => l.RemoveLocation(key));
}
精彩评论