开发者

C# searching for new Tool for the tool box, how to template this code

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));     
} 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜