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));
}
加载中,请稍侯......
精彩评论