Skip to content

aglebov-dev/Dioxide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Dioxide

https://www.nuget.org/packages/Dioxide/

Install-Package Dioxide

Getting Started

Proxy

The decorator uses the IProxyInterceptor interface. It is necessary to create an interface implementation that will be called inside the generated type For sample:

public class MetricsInterceptor : IProxyInterceptor
{
    private Stopwatch stopwatch;
    private readonly ILogger _logger;

    public MetricsInterceptor(ILogger logger)
    {
        _logger = logger;
    }

    public void Enter(string methodName, IMethodArgs args)
    {
        stopwatch = Stopwatch.StartNew();
    }

    public void Exit(string methodName, IMethodArgs args, IMethodResult result)
    {
        _logger.Log($"Successful method {methodName}. Total time: {stopwatch.ElapsedMilliseconds} ms");
    }

    public void Finaly(string methodName, IMethodArgs args, IMethodResult result) 
    { 
        stopwatch.Stop();  
    }

    public Exception Catch(string methodName, IMethodArgs args, Exception exception)
    {
        _logger.Log($"Failed method {methodName}. Total time: {stopwatch.ElapsedMilliseconds} ms");
        return exception;
    }
}

Create the necessary types using the builder

public interface IDoSomthing
{
    void DoSomething();
    Task<int> GoTask(string name, int delay);
    int GetInteger(int value, int args, string client);
}
var buildResult = new DioxideTypeBuilder(default)
    .GenerateDecorator<IDoSomthing>(x =>
    {
        x.With<MetricsInterceptor>();
    })
    .Build();

Register types in container (using autofac container)

if (buildResult.IsSuccess)
{
    foreach (var item in buildResult.Types)
    {
        builder.RegisterDecorator(item.GeneratedType, item.OriginType);
    }
}

What will be generated (InterceptorsGroup - implements the IProxyInterceptor interface and combines within itself the calls of the IProxyInterceptor implementations)

public sealed class IDoSomthing_X290665897f994f1a9874d7ce855348d4 : global::Dioxide.Samples.Proxy.IDoSomthing
{
    private readonly global::Dioxide.Contracts.InterceptorsGroup _interseptors;
    private readonly global::Dioxide.Samples.Proxy.IDoSomthing _client;
    public IDoSomthing_X290665897f994f1a9874d7ce855348d4(global::Dioxide.Samples.Proxy.IDoSomthing client, global::Dioxide.Samples.Proxy.Interseptors.LogInterceptor logInterceptor)
    {
        _client = client;
        _interseptors = new global::Dioxide.Contracts.InterceptorsGroup();
        _interseptors.Add(logInterceptor as global::Dioxide.Contracts.IProxyInterceptor);
    }
    
    //method without result
    public void DoSomething()
    {
        var method = "DoSomething";
        var args = new global::Dioxide.Contracts.MethodArgs();
        var result = new global::Dioxide.Contracts.MethodResult();
        try
        {
            _interseptors.Enter(method, args);
            _client.DoSomething();
            _interseptors.Exit(method, args, result);
        }
        catch (global::System.Exception ex)
        {
            var exception = _interseptors.Catch(method, args, ex);
            if (exception == null)
            {
                throw;
            }
            else
            {
                throw exception;
            }
        }
        finally
        {
            _interseptors.Finaly(method, args, result);
        }
    }
    
    //method with async result
    public async global::System.Threading.Tasks.Task<int> GoTask(string name, int delay)
    {
        var method = "GoTask";
        var args = new global::Dioxide.Contracts.MethodArgs();
        var result = new global::Dioxide.Contracts.MethodResult();
        args.Set("name", name);
        args.Set("delay", delay);
        try
        {
            _interseptors.Enter(method, args);
            var methodResult = await _client.GoTask(name, delay);
            result.Set(methodResult);
            _interseptors.Exit(method, args, result);
            return methodResult;
        }
        catch (global::System.Exception ex)
        {
            var overrideResult = _interseptors.CatchOverrideResult(method, args, ex);
            if (overrideResult.HasResult<global::System.Threading.Tasks.Task<int>>())
            {
                _interseptors.Exit(method, args, overrideResult);
                return await overrideResult.GetResultOrDefault<global::System.Threading.Tasks.Task<int>>();
            }

            var exception = _interseptors.Catch(method, args, ex);
            if (exception == null)
            {
                throw;
            }
            else
            {
                throw exception;
            }
        }
        finally
        {
            _interseptors.Finaly(method, args, result);
        }
    }
    
    //method with sync result
    public int GetInteger(int value, int args, string _client1)
    {
        var method = "GetInteger";
        var args1 = new global::Dioxide.Contracts.MethodArgs();
        var result = new global::Dioxide.Contracts.MethodResult();
        args1.Set("value", value);
        args1.Set("args", args);
        args1.Set("_client", _client1);
        try
        {
            _interseptors.Enter(method, args1);
            var methodResult = _client.GetInteger(value, args, _client1);
            result.Set(methodResult);
            _interseptors.Exit(method, args1, result);
            return methodResult;
        }
        catch (global::System.Exception ex)
        {
            var overrideResult = _interseptors.CatchOverrideResult(method, args1, ex);
            if (overrideResult.HasResult<int>())
            {
                _interseptors.Exit(method, args1, overrideResult);
                return overrideResult.GetResultOrDefault<int>();
            }

            var exception = _interseptors.Catch(method, args1, ex);
            if (exception == null)
            {
                throw;
            }
            else
            {
                throw exception;
            }
        }
        finally
        {
            _interseptors.Finaly(method, args1, result);
        }
    }
}

About

Roslyn-based in memory type generation library (only Proxy is available now)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages