Giter VIP home page Giter VIP logo

norns.urd's Introduction

Norns.Urd

build GitHub GitHub Repo stars

Nuget Packages

Package Name NuGet Downloads
Norns.Urd Nuget Nuget
Norns.Urd.Extensions.Polly Nuget Nuget
Norns.Urd.Caching.Abstractions Nuget Nuget
Norns.Urd.Caching.Memory Nuget Nuget
Norns.Urd.Caching.DistributedCache Nuget Nuget
Norns.Urd.HttpClient Nuget Nuget
Norns.Urd.HttpClient.NewtonsoftJson Nuget Nuget

Welcome to Norns.Urd

Norns.urd is a lightweight AOP framework based on emit which do dynamic proxy.

It base on netstandard2.0.

The purpose of completing this framework mainly comes from the following personal wishes:

  • Static AOP and dynamic AOP are implemented once
  • How can an AOP framework only do dynamic proxy but can work with other DI frameworks like Microsoft.Extensions.DependencyInjection
  • How can an AOP make both sync and Async methods compatible and leave implementation options entirely to the user

Hopefully, this library will be of some useful to you

Fundamentals

  • Interceptor
    • Attribute Interceptor
    • Global interceptor
  • Generate default implementation of Interface and Abstract Class
  • InjectAttribute
    • PropertyInject
    • ParameterInject
    • FieldInject
  • FallbackAttribute
  • Polly
    • TimeoutAttribute
    • RetryAttribute
    • CircuitBreakerAttribute
    • BulkheadAttribute
  • CacheAttribute (support Multistage cache with memory cache and distributed cache)

How to use

Quick start

This is simple demo whch to do global interceptor, full code fot the demo you can see Examples.WebApi

  1. create ConsoleInterceptor.cs

    using Norns.Urd;
    using Norns.Urd.Reflection;
    using System;
    using System.Threading.Tasks;
    
    namespace Examples.WebApi
    {
        public class ConsoleInterceptor : AbstractInterceptor
        {
            public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
            {
                Console.WriteLine($"{context.Service.GetType().GetReflector().FullDisplayName}.{context.Method.GetReflector().DisplayName}");
                await next(context);
            }
        }
    }
  2. set WeatherForecastController's method be virtual

    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        [HttpGet]
        public virtual IEnumerable<WeatherForecast> Get() => test.Get();
    }
  3. AddControllersAsServices

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers().AddControllersAsServices();
    }
  4. add GlobalInterceptor to di

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers().AddControllersAsServices();
        services.ConfigureAop(i => i.GlobalInterceptors.Add(new ConsoleInterceptor()));
    }
  5. run

    you will see this in console

    Norns.Urd.DynamicProxy.Generated.WeatherForecastController_Proxy_Inherit.IEnumerable<WeatherForecast> Get()

Deep Document

中文文档 | Document

Roadmap

  • AOP
  • Polly
  • Cache
  • HttpClient
  • Trace
  • Runtime Metrics collect

Simple Benchmark

Just simple benchmark test, and does not represent the whole scenario

Castle and AspectCore are excellent libraries,

Many implementations of Norns.urd refer to the source code of Castle and AspectCore.

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19044.1288/21H2/November2021Update)
Intel Core i7-10700 CPU 2.90GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.402
  [Host]     : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2
  DefaultJob : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2


|                                         Method |      Mean |    Error |   StdDev |   Gen0 | Allocated |
|----------------------------------------------- |----------:|---------:|---------:|-------:|----------:|
|       TransientInstanceCallSyncMethodWhenNoAop |  52.41 ns | 0.319 ns | 0.298 ns | 0.0134 |     112 B |
|    TransientInstanceCallSyncMethodWhenNornsUrd | 120.26 ns | 0.237 ns | 0.185 ns | 0.0410 |     344 B |
|      TransientInstanceCallSyncMethodWhenCastle | 168.58 ns | 0.842 ns | 0.788 ns | 0.0610 |     512 B |
|  TransientInstanceCallSyncMethodWhenAspectCore | 439.43 ns | 1.466 ns | 1.225 ns | 0.0772 |     648 B |
|      TransientInstanceCallAsyncMethodWhenNoAop |  88.63 ns | 0.318 ns | 0.282 ns | 0.0305 |     256 B |
|   TransientInstanceCallAsyncMethodWhenNornsUrd | 211.48 ns | 1.315 ns | 1.098 ns | 0.0668 |     560 B |
|     TransientInstanceCallAsyncMethodWhenCastle | 197.95 ns | 0.657 ns | 0.549 ns | 0.0782 |     656 B |
| TransientInstanceCallAsyncMethodWhenAspectCore | 522.63 ns | 4.313 ns | 4.034 ns | 0.1030 |     864 B |

## License
[MIT](https://github.com/fs7744/Norns.Urd/blob/main/LICENSE)

norns.urd's People

Contributors

fs7744 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

norns.urd's Issues

start urd

  1. move caller to static proxy type
  2. init static proxy type when type created
  3. support method overload

Hangfire is not supported

On .net 6
Hangfire 1.7
Norns.Urd 0.0.4.6

Could not load file or assembly 'Norns.Urd.DynamicProxy.Generated

thow error on Hangfire run job

[11:55:35 WRN] Recurring job 'MyLogWorker' can't be scheduled due to an error and will be retried in 00:00:15.
System.InvalidOperationException: Recurring job can't be scheduled, see inner exception for details.
 ---> Hangfire.Common.JobLoadException: Could not load the job. See inner exception for the details.
 ---> System.IO.FileNotFoundException: Could not load file or assembly 'Norns.Urd.DynamicProxy.Generated, Culture=neutral, PublicKeyToken=null'. 系统找不到指定的文件。
File name: 'Norns.Urd.DynamicProxy.Generated, Culture=neutral, PublicKeyToken=null'
   at System.Reflection.RuntimeAssembly.InternalLoad(ObjectHandleOnStack assemblyName, ObjectHandleOnStack requestingAssembly, StackCrawlMarkHandle stackMark, Boolean throwOnFileNotFound, ObjectHandleOnStack assemblyLoadConte
xt, ObjectHandleOnStack retAssembly)
   at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName assemblyName, RuntimeAssembly requestingAssembly, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, AssemblyLoadContext assemblyLoadContext)
   at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
   at Hangfire.Common.TypeHelper.AssemblyResolver(String assemblyString)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)

autofac 下不生效

        builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .ConfigureContainer<ContainerBuilder>((hostBuilderContext, containerBuilder) =>
        {

        });

do Polly

implementation Polly attribute as demo to show aop power

.NET 8.0 Asp.Versioning.Mvc and ConfigureAop, IApiVersionParser.TryParse(ReadOnlySpan) error

I have Norns.Urd v.0.0.4.7 and installed Asp.Versioning.Mvc in version 8.1.0.
When I add builder.Services.ConfigureAop(); in Program.cs application throws exception when it try to reach any endpoint
that require api version.
For example, for endpoint
http://localhost:5253/v1/weatherforecast
it throws exception:

An unhandled exception occurred while processing the request.
InvalidProgramException: Common Language Runtime detected an invalid program.
Norns.Urd.DynamicProxy.Generated.ApiVersionParser_Proxy_Inherit.Asp.Versioning.IApiVersionParser.TryParse(ReadOnlySpan<char> text, out ApiVersion apiVersion)

Stack:

InvalidProgramException: Common Language Runtime detected an invalid program.
Norns.Urd.DynamicProxy.Generated.ApiVersionParser_Proxy_Inherit.Asp.Versioning.IApiVersionParser.TryParse(ReadOnlySpan<char> text, out ApiVersion apiVersion)
Asp.Versioning.Routing.ApiVersionRouteConstraint.Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
Microsoft.AspNetCore.Routing.Matching.DfaMatcher.ProcessConstraints(Endpoint endpoint, KeyValuePair<string, IRouteConstraint>[] constraints, HttpContext httpContext, RouteValueDictionary values)
Microsoft.AspNetCore.Routing.Matching.DfaMatcher.MatchAsync(HttpContext httpContext)
Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Steps to reproduce
Application ASP.NET Core Web API generated from template in Visual Studio with .NET 8.0.
To application we have to add two nuget packages:

  • Asp.Versioning.Mvc in version 8.1.0
  • Norns.Urd in version 0.0.4.7

Next, in Program.cs file add below lines:

builder.Services.AddApiVersioning(options =>
{
    options.ReportApiVersions = true;
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
});

and:
builder.Services.ConfigureAop();

in this way (between AddControllers and builder.Build()):

builder.Services.AddControllers();
builder.Services.AddApiVersioning(options =>
{
    options.ReportApiVersions = true;
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
});
builder.Services.ConfigureAop();
var app = builder.Build();

In WeatherForecastController comment [Route("[controller]")] attribute and add two attributes like that:

[ApiController]
[ApiVersion("1.0")]
[Route("v{version:apiVersion}/[controller]")]
//[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{

Start application and change in browser the url from
http://localhost:5253/weatherforecast (generated automatically)
to this one:
http://localhost:5253/v1/weatherforecast

Application will start and throw exception.

Repository with example of application to reproduce bug:
https://github.com/robertgm/VersioningMvcAopBug

doc

  • 1. attribute
  • 2. nonaspect
  • 3. inject
  • 4. interface class no inherit
  • 5. limit

Docs for http client?

Just exploring your projects, looks really good, and could be very useful, nice work!

It would be good to have some docs for the http client functionality. Which features can it cope with:-

  1. Multipart requests?
  2. File Uploads? IFormFile ?
  3. All different verbs (POST, PUT, PATCH etc)
  4. Cancellation tokens?
  5. Use of Polly - retry?
  6. Use of Cache on GET methods to avoid making http call?
  7. Multipart responses?
  8. File downloads?

support .NETStandard 2.0

net 5.0 的 匹配模式语法糖玩高兴了,现在应该切换回 .NETStandard 2.0 了 囧

方法在async下,throw异常,会抛出AggregateException 发生一个或多个错误。

调用方法为

 public virtual async Task DoAsync()
            {
                if (Count < 50)
                {
                    Count++;
                    throw new FieldAccessException();
                }

                await Task.Yield();

            }

在IInterceptorCreator.cs中,注释一下三行代码即可解决

 public static async Task Await(Task task)
        {
            //if (!task.IsCompleted)
            {
                await task;
            }
        }

        public static async Task AwaitValueTask(ValueTask task)
        {
            //if (!task.IsCompleted)
            {
                await task;
            }
        }

        public static async Task AwaitValueTaskReturnValue<T>(ValueTask<T> task)
        {
            //if (!task.IsCompleted)
            {
                await task;
            }
        }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.