Giter Site home page Giter Site logo

dotnetcore / natasha Goto Github PK

View Code? Open in Web Editor NEW
1.4K 68.0 211.0 28.06 MB

基于 Roslyn 的 C# 动态程序集构建库,该库允许开发者在运行时使用 C# 代码构建域 / 程序集 / 类 / 结构体 / 枚举 / 接口 / 方法等,使得程序在运行的时候可以增加新的模块及功能。Natasha 集成了域管理/插件管理,可以实现域隔离,域卸载,热拔插等功能。 该库遵循完整的编译流程,提供完整的错误提示, 可自动添加引用,完善的数据结构构建模板让开发者只专注于程序集脚本的编写,兼容 stanadard2.0 / netcoreapp3.0+, 跨平台,统一、简便的链式 API。 且我们会尽快修复您的问题及回复您的 issue.

Home Page: https://natasha.dotnetcore.xyz/

License: MIT License

C# 99.45% Python 0.53% Batchfile 0.01% Shell 0.01%
il csharp roslyn script dynamic dotnetcore hacktoberfest

natasha's Introduction

中文 | English

你们的反馈是我的动力,文档还有很多不足之处;

当你看完文档之后仍然不知道如何实现你的需求,您可以查看 FAQ 或者在issue中提出你的需求。


Natasha

Member project of .NET Core Community Gitter Badge GitHub license wiki
Compile NuGet Badge GitHub commit activity Codecov UT Test From PR



    基于 [Roslyn](https://github.com/dotnet/roslyn) 的 C# 动态程序集构建库,该库允许开发者在运行时使用 C# 代码构建域 / 程序集 / 类 / 结构体 / 枚举 / 接口 / 方法等,使得程序在运行的时候可以增加新的模块及功能。Natasha 集成了域管理/插件管理,可以实现域隔离,域卸载,热拔插等功能。 该库遵循完整的编译流程,提供完整的错误提示, 可自动添加引用,完善的数据结构构建模板让开发者只专注于程序集脚本的编写,兼容 netstandard2.0, 跨平台,统一、简便的链式 API。 且我们会尽快修复您的问题及回复您的 [issue](https://github.com/dotnetcore/Natasha/issues/new) . [这里有更多的使用文档](https://natasha.dotnetcore.xyz/zh-Hans/docs)

展示



性能测试

  • 动态初始化性能测试(对照组: emit, origin)
    初始化性能测试
  • 内存及CPU监测截图
    内存及CPU


赞助:

捐助明细

  • 亮 20元
  • 升讯威在线客服系统 5元
  • Json-jh [尊敬的博客园VIP会员] 22元
  • Newbe俞佬 90.2 元
  • 崔星星 17 元
  • Money 100 元
  • Newbe俞佬 200 元
  • iNeuOS工业互联网平台 100 元
  • 老萌 30 元
  • ****天下 10 元
  • 文航 5 元
  • TonyQu 10 元
  • Rwing 20 元

感谢老铁们的支持,感激不尽 🙏🙏🙏。



License

FOSSA Status

natasha's People

Contributors

alexinea avatar dependabot[bot] avatar fs7744 avatar mzorec avatar newbe36524 avatar nmsazulx avatar ran-snow avatar renovate-bot avatar weihanli avatar wlclass 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

natasha's Issues

Natasha 预热优化

我原本是使用NatashaInitializer.Initialize();
使用是正常的,但是我每次调用构建都要2秒的时间,感觉太费时间了。
所以就想到了InitializeAndPreheating();,可是我调用这个就报错。

Natasha版本:3.1.0.0
测试代码和错误信息如下:

测试代码:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Natasha.CSharp;
using System.Threading.Tasks;

namespace MyNameSpace
{
    [TestClass()]
    public class MyClassTest
    {
        [TestMethod()]
        public void Natasha_测试()
        {
            //仅仅注册组件 这个初始化是可以正常使用的,就是每次都要2秒左右,很耗费时间。
            NatashaInitializer.Initialize();
            for (int i = 0; i < 10; i++)
            {
                var start = DateTime.Now;
                Natasha测试一次();
                Console.WriteLine($"第{i}次查询用时:{(DateTime.Now - start).TotalSeconds}秒");
            }
        }
        [TestMethod()]
        public async Task Natasha_测试Async()
        {
            //注册+预热组件 , 之后编译会更加快速 可是这个调用报错了,想知道我应该怎么做
            await NatashaInitializer.InitializeAndPreheating();
            for (int i = 0; i < 10; i++)
            {
                var start = DateTime.Now;
                Natasha测试一次();
                Console.WriteLine($"第{i}次查询用时:{(DateTime.Now - start).TotalSeconds}秒");
            }
        }
        private void Natasha测试一次()
        {
            var newClassName = $"{nameof(BaseModel)}_{new Random().Next(int.MaxValue)}";
            var action = FastMethodOperator.DefaultDomain(option =>
            {
                option.Add($@"
                namespace MyNameSpace
                {{
                    public class {newClassName} : {nameof(BaseModel)}
                    {{
                        public override string Name => ""OveName"";
                    }}
                }}");
            })
            .Param(typeof(string), "inValue")
            .Body($@"
                var obj = new {newClassName}();
                return obj.Show(inValue);
                ")
            .Return<string>()
            .Compile<Func<string, string>>();
            var result = action("aaabbb");
            Console.WriteLine($"result:{result}");
        }
    }
    public class BaseModel
    {
        public virtual string Name => "BaseName";
        public string Show(string inValue)
        {
            Console.WriteLine($"ClassName:{this.GetType().Name},Name:{Name},InValue:{inValue}");
            return $"Result {inValue}";
        }
    }
}

错误信息:

 Natasha_测试Async
   源: ZzwTest.cs 行 24
   持续时间: 2.1 秒

  消息: 
    Test method MyNameSpace.MyClassTest.Natasha_测试Async threw exception: 
    Natasha.Error.NatashaException: 编译错误 : CS8021 找不到 RuntimeMetadataVersion 的值。找不到包含 System.Object 的程序集,或未通过选项为 RuntimeMetadataVersion 指定值。
  堆栈跟踪: 
    AssemblyCSharpBuilder.GetAssembly()
    AssemblyBuilderExtension.GetTypeFromShortName(AssemblyCSharpBuilder builder, String typeName)
    AssemblyBuilderExtension.GetMethodFromShortName(AssemblyCSharpBuilder builder, String typeName, String methodName)
    AssemblyBuilderExtension.GetDelegateFromShortName(AssemblyCSharpBuilder builder, String typeName, String methodName, Type delegateType, Object target)
    AssemblyBuilderExtension.GetDelegateFromShortName[T](AssemblyCSharpBuilder builder, String typeName, String methodName, Object target)
    MethodBuilder`1.Compile[S](Object target)
    DelegateOperator`1.Delegate(String content, AssemblyCSharpBuilder builder, Action`1 option, Func`2 methodAction, Func`2 oopAction, NamespaceConverter[] usings)
    NDelegate.Action(String content)
    NatashaInitializer.InitializeAndPreheating(Boolean initializeReference)
    MyClassTest.Natasha_测试Async() 行 27
    ThreadOperations.ExecuteWithAbortSafety(Action action)

Originally posted by @zhangzw218 in #68

你好,有没有升级到dotnet6的计划,我遇到了版本冲突

大概的冲突代码如下:

` 严重性 代码 说明 项目 文件 行 禁止显示状态 错误
NU1107 Microsoft.CodeAnalysis.Common 中检测到版本冲突。直接安装/引用 Microsoft.CodeAnalysis.Common 4.0.0 到项目 可解决此问题。
Volo.Abp.AspNetCore.Mvc 5.3.4 -> Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 6.0.5 -> Microsoft.CodeAnalysis.Razor 6.0.5 -> Microsoft.CodeAnalysis.Common (>= 4.0.0)

DotNetCore.Natasha.CSharp.All 3.6.0 -> DotNetCore.Natasha.CSharp.Template 3.6.0 -> DotNetCore.Natasha.CSharp.Engine 3.6.0 -> Microsoft.CodeAnalysis.CSharp.Workspaces 3.11.0 -> Microsoft.CodeAnalysis.Common (= 3.11.0). FJMarket.QuestionMiniProgram.InterfaceWeb `

我尝试通过安装更高版本解决问题,但遇到了新的错误:
Unable to load one or more of the requested types.
Method 'get_MetadataToken' in type 'Microsoft.CodeAnalysis.CodeGeneration.CodeGenerationArrayTypeSymbol' from assembly 'Microsoft.CodeAnalysis.Workspaces, Version=3.11.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not have an implementation.
想知道,你们有没有更新到net6的计划?

增加类的xml生成

编译类后能够根据类的注释生成类的xml文档,可以用于动态生成api时swagger可以解析出注释用。

请问方法编译如何捕获编译异常呢?

例如下面的代码,是段缺少分号的错误代码,在使用中如何捕获编译异常信息呢,现在编译失败只能判断action是null,并不能获得异常信息。
`
var test_action = FastMethodOperator.New
.Param("param")
.MethodBody("return param ")
.Return()
.Complie<Func<object, object>>();

test_action("hello");
`

支持从 Stream 加载 Assembly 依赖项

在 Blazor 环境中依赖项的 Assembly 无法以 File 的形式存在。因此需要从特定的 Stream 中加载 Assembly。
虽然我没看代码,但是我猜测现在必须从文件加载依赖项。
(手动滑稽)

这将有助于下一步为开发 Web 页面上可用的 Natasha 提供助力。

4.2 demo 无法使用。代码也不对。

引用Natasha.CSharp, Version=4.2.0.0

执行以下代码
` public void TestCorder() {

        //NatashaInitializer.Preheating();
        NatashaManagement.Preheating();
        //增加全局的 Using 引用
        NatashaManagement.AddGlobalUsing("System");
        NatashaManagement.AddGlobalUsing("System.IO");
        //使用 Natasha 的 CSharp 编译器直接编译字符串
        AssemblyCSharpBuilder sharpBuilder = new AssemblyCSharpBuilder(); 
        //给编译器指定一个随机域
        //sharpBuilder.Domain = DomainManagement.Random();

        sharpBuilder.UseNatashaFileOut("c:/output");

        //如果代码编译错误,那么抛出并且记录日志。
        sharpBuilder.CompileFailedEvent += (compilation, errors) =>
        {
            var errorLog = compilation.Assembly;
        };


        //添加你的字符串
        sharpBuilder.Add("using System; public static class Test{ public static void Show(){ Console.WriteLine(\"Hello World!\");}}");
        //编译出一个程序集
        var assembly = sharpBuilder.GetAssembly();


        //如果你想直接获取到类型
        var type = sharpBuilder.GetTypeFromShortName("Test");
        //或
        type = sharpBuilder.GetTypeFromFullName("xxNamespace.xxClassName");

//创建一个 Action 委托
//必须在同一域内,因此指定域
//写调用脚本,把刚才的程序集扔进去,这样会自动添加using引用
var action = NDelegate.UseDomain(sharpBuilder.Domain).Action("Test.Show();");//, assembly

        //运行,看到 Hello World!
        action();

    }`

报错:
image

运行官网示例出错.

.net core 3.1 控制台项目
nuget DotNetCore.Natasha.CSharp 5.0.2

https://natasha.dotnetcore.xyz/zh-Hans/docs/00-1-Why 复制代码到Main方法中, 代码如下

static void Main(string[] args)
{
//初始化 Natasha 编译组件及环境
NatashaInitializer.Preheating();
//创建编译单元,并指定程序集名
AssemblyCSharpBuilder oop = new AssemblyCSharpBuilder("myAssembly");
//编译单元使用从域管理分配出来的随机域
oop.Domain = DomainManagement.Random();
//增加代码到编译单元中
oop.Add(@"namespace HelloWorld{ public class Test{ public Test(){ Name = null; } public string Name; } }");
//根据短名获取程序集中的类,长名则如 "HelloWorld.Test"
Type type = oop.GetTypeFromShortName("Test");

        Console.WriteLine("Hello World!");
    }

运行后报错.

报错信息为:
NatashaException:“找不到 RuntimeMetadataVersion 的值。找不到包含 System.Object 的程序集,或未通过选项为 RuntimeMetadataVersion 指定值。”

网卡了, 问题发重复了..

.net core2.2 web工程使用发布后运行异常

在.net core2.2环境下,使用vs2017开发web,调试运行没有任何问题,动态编译正常运行。独立发布后运行出现异常,主要异常信息如下:

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
   at System.String.Substring(Int32 startIndex, Int32 length)
   at Natasha.Complier.ScriptComplierEngine.GetErrorString(String content, FileLinePositionSpan linePositionSpan) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Engine\ComplierModule\ScriptComplierEngine.cs:line 428
   at Natasha.Complier.ScriptComplierEngine.StreamComplier(String sourceContent, String& formatContent, Action`1 errorAction) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Engine\ComplierModule\ScriptComplierEngine.cs:line 202
   at Natasha.IComplier.GetAssemblyByScript(String content) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Engine\Standard\IComplier.cs:line 69
   at Natasha.IComplier.GetTypeByScript(String content, String typeName) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Engine\Standard\IComplier.cs:line 105
   at Natasha.IComplier.GetMethodByScript(String content, String typeName, String methodName) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Engine\Standard\IComplier.cs:line 138
   at Natasha.IComplier.GetDelegateByScript(String content, String typeName, String methodName, Type delegateType, Object binder) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Engine\Standard\IComplier.cs:line 174
   at Natasha.IComplier.GetDelegateByScript[T](String content, String typeName, String methodName, Object binder) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Engine\Standard\IComplier.cs:line 205
   at Natasha.Complier.MethodComplier.Complie[T](String className, String content, String methodName, Object binder) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Complier\MethodComplier.cs:line 45
   at Natasha.Builder.OnceMethodBuilder`1.Complie[T](Object binder) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Builder\OnceMethodBuilder.cs:line 51
   at Natasha.FastMethodOperator.Complie[T](Object binder) in C:\Users\wenjq\Downloads\Natasha-master\src\Natasha\Operator\FastMethodOperator.cs:line 57

尝试附件进程调试,发现在ScriptComplierEngine的StreamComplier方法,诊断信息中产生了大量的警告信息,导致GetErrorString出错。修改代码只取Error信息后得到下面的错误提示:

------------------------------------------error----------------------------------------------

    Time :		2019-08-06 15:32:30

    Lauguage :	C# & CSharp7_3

    Target:		System.String[]

    Error:		共9处错误!
		第7行,第20个字符:       内容【N88d54917fd80421d93a7d1d1eee7587f】  预定义类型“System.Object”未定义或导入
		第9行,第46个字符:       内容【Object】  预定义类型“System.Object”未定义或导入
		第9行,第46个字符:       内容【Object】  未能在命名空间“System”中找到类型名“Object”。此类型已转发到程序集“System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e”。请考虑添加对该程序集的引用。
		第9行,第18个字符:       内容【Object】  预定义类型“System.Object”未定义或导入
		第9行,第18个字符:       内容【Object】  未能在命名空间“System”中找到类型名“Object”。此类型已转发到程序集“System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e”。请考虑添加对该程序集的引用。
		第12行,第27个字符:       内容【List<object>】  预定义类型“System.Object”未定义或导入
		第12行,第27个字符:       内容【List<object>】  未能在命名空间“System.Collections.Generic”中找到类型名“List<>”。此类型已转发到程序集“System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e”。请考虑添加对该程序集的引用。
		第12行,第32个字符:       内容【object】  预定义类型“System.Object”未定义或导入

---------------------------------------------------------------------------------------------

web工程直接是在源码的samples下创建的一个基于.net core2.2的 mvc工程,直接引用Natasha类库,动态编译的代码也很简单,只在生成的HomeController中随意增加了一段代码

       public IActionResult Index()
        {
            var code = @"
                var res_list = new List<object>();
                return res_list;
            ";

            FastMethodOperator.New.Using(new string[] { "System", "System.Linq", "System.Collections.Generic", " System.IO", "System.Threading.Tasks", "Newtonsoft.Json" })
                                .Param<object>("p")
                                .MethodBody(code)
                                .Return<object>()
                                .Complie<Func<object, object>>();

            Console.WriteLine("OK");

            return View();
        }

不知对于web工程是否还有特殊设置?

4.0.0-beta.1现在能用吗?

我试了,没有NatashaInitializer.InitializeAndPreheating();方法。 NDomain也没有。这个版本现在是什么情况了呢?

💡 提 issue 请看,何时需移步到 Discussion 💡

今日(2020年12月09日)我们惊奇的发现,Github 上线了 Discussion 功能,为此我们将对以后的 issue 做出区分。

Issue

当前 issue 区对开发者来讲,是个比较重要且正式的成长源头,这里更多是跟源代码直接相关的问题,该区域被严格管理。该区所接收的问题:

  • BUG 报告
  • 详细的 API 建议
  • 性能问题
  • 安全漏洞
  • 以及与本库紧密相关的上游项目的上述4类问题

Discussions

我建议更轻松的讨论转移到讨论区

  • 令您困扰的应用问题。
  • 大胆分享你对该库的规划建议以及设计灵感。
  • 和贡献者们进行一些有趣的互动。
  • 像个小论坛,比起 ISSUE 这里就像我们工作时,午休时间那样轻松的聊天, 它不限语言,并且讨论是长期处于打开状态。

这个项目的需求是什么?是要解决什么问题?

如果使用插件的话,那直接jekins编译就好了,为什么要用源码?
如果说是动态编译,直接用IL更方便快捷,且效率也高.
如果说是隔离工作,AppLoadContext也挺不错的.
我实在不明白这个项目的意义在哪里?

第一次动态编译慢

用了DelegateOperator.CreateUsingStrings 进行动态构建调用一个方法,发现是每次第一次动态构建的时候都非常慢。

Identifier expected

natasha 4.2
.netcore 6

类型定义如下

using EasyOC.Core.Indexes;
using FreeSql.DataAnnotations; 
// 此代码由程序生成,复制到代码文件后请更新命名空间,
// 或者在命名空间处点击 Alt+Enter 自动更新命名空间
namespace EasyOC.DynamicTypeIndex.Default.IndexModels
{
    [EOCIndex("IDX_{tablename}_DocumentId","ContentItemId,DocumentId,Published,Latest")]
    [EOCTable(Name = "DIndex_Customer")]
    public class CustomerDIndex : DIndexBase
    { 
        [Column(Name = "Name",IsNullable = true,StringLength = -1)]
        public string Name { get; set; }
                
        [Column(Name = "CustNum",IsNullable = true,StringLength = -1)]
        public string CustNum { get; set; }
                
        [Column(Name = "MarketSegment",IsNullable = true,StringLength = 26)]
        public string MarketSegment { get; set; }
                
        [Column(Name = "Source",IsNullable = true,StringLength = 26)]
        public string Source { get; set; }
                
        [Column(Name = "Industry",IsNullable = true,StringLength = 26)]
        public string Industry { get; set; }
                
        [Column(Name = "CustClass",IsNullable = true,StringLength = 26)]
        public string CustClass { get; set; }
                
        [Column(Name = "SalesOwner",IsNullable = true,StringLength = 26)]
        public string SalesOwner { get; set; }
                
        [Column(Name = "Guimo",IsNullable = true,StringLength = -1)]
        public string Guimo { get; set; }
                
        [Column(Name = "CustomerRemark",IsNullable = true,StringLength = -1)]
        public string CustomerRemark { get; set; }
                
        [Column(Name = "dateeeee",IsNullable = true)]
        public System.DateTime dateeeee { get; set; }
                
        [Column(Name = "datetimesssssss",IsNullable = true)]
        public System.DateTime datetimesssssss { get; set; }
                
        [Column(Name = "timeeeeeeeeeee",IsNullable = true,StringLength = -1)]
        public string timeeeeeeeeeee { get; set; }
                
        [Column(Name = "AddressPart_CountryName",IsNullable = true,StringLength = -1)]
        public string AddressPartCountryName { get; set; }
                
        [Column(Name = "AddressPart_Province",IsNullable = true,StringLength = -1)]
        public string AddressPartProvince { get; set; }
                
        [Column(Name = "AddressPart_City",IsNullable = true,StringLength = -1)]
        public string AddressPartCity { get; set; }
                
        [Column(Name = "AddressPart_PostalCode",IsNullable = true,StringLength = -1)]
        public string AddressPartPostalCode { get; set; }
                
        [Column(Name = "AddressPart_Details",IsNullable = true,StringLength = -1)]
        public string AddressPartDetails { get; set; }
                
        [Column(Name = "AddressPart_Name",IsNullable = true,StringLength = -1)]
        public string AddressPartName { get; set; }
                
    }
}

调用代码:

public virtual Task<AssemblyCSharpBuilder> GetAssemblyCSharpBuilderAsync(
            bool useGlobalSharedBuilder = true)
        {
            NatashaInitializer.Preheating();
            return Task.FromResult(new AssemblyCSharpBuilder());
        }

        /// <summary>
        /// 添加类型
        /// </summary>
        /// <param name="fullName"></param>
        /// <param name="cSharpScripts"></param>
        /// <param name="usings"> 只包含命名空间,不含 using  xxx.xxx.xxx ;
        ///如: System.Text</param>
        /// <returns></returns>
        public virtual async Task<Type> CreateTypeAsync(string fullName, string cSharpScripts,
            IEnumerable<string> usings = default)
        {
            try
            {
                var builder = await GetAssemblyCSharpBuilderAsync(false);
                //只包含命名空间,不含 using  xxx.xxx.xxx ;
                //如: System.Text
                if (usings != null)
                {
                    builder.Domain.UsingRecorder.Using(usings);// 全局引用
                }
                builder.Add(cSharpScripts);
                var asm = builder.GetAssembly();

                var type = asm.GetType(fullName);

                if (_types.ContainsKey(fullName))
                {
                    _types[fullName] = type;
                }
                else
                {
                    _types.Add(fullName, type);
                }

                return type;
            }
            catch (Exception e)
            {
                _logger.LogError(e, "脚本编译错误,{error}", e.Message);//
                Console.WriteLine(e);
                throw new Exception("模型映射解析错误");
            }
        }

image

((NatashaException)e).Formatter

image

在netcore3.1的aspnetcore项目里跑不起来啊。

1 通过nuget引用的方式
netcoreapp3.1
true
false
这个也加了。 报Microsoft.AspNetCore.Antiforgery.dll找不到.

2 直接在您的项目的源码里,新建webapi项目。则直接报natasha的2.8.11 的ll找不到。

可序列化的抽象表达式

在分布式应用中,遇到在client编写函数,通过特定机制允许client函数可以在不同server节点中远程执行的需求。
基于此需求,natasha是否支持构造可序列化的IL抽象表达式,允许在远端解析此表达式从而动态构造可执行函数?

Who is using Natasha?(欢迎使用 Natasha 的个人和公司在此留言)

Who is using Natasha?

Sincerely thank everyone who constantly keeps on using and supporting Natasha. We will try our best to make Natasha better and make the community and ecology more prosperous.

The original intention of this issue

  • We’d like to listen to the community to make Natasha better.
  • We want to attract more partners to contribute to Natasha.
  • Learn more about the practical use scenarios of Natasha to facilitate the next step of planning.

What we expect from you

Please submit a comment in this issue to include the following information:

your company, school or organization.
your city and country.
your contact info: blog, email, twitter (at least one).
for what business scenario do you use Natasha.

You can refer to the following sample answer:

Organization: nms
Location: Beijing, China
Contact: [email protected]
Purpose: Write open source class libraries based on Natasha.

Thanks again for your participation! Your support is the motivation for us to move forward.
NCC Natasha community

谁在使用 Natasha ?

感谢正在使用和关注 Natasha 的开发者,我们会持续投入,让 Natasha 项目和社区更加繁荣。

这个 issue 的出发点

  • 聆听社区的声音,让 Natasha 解决实际的问题
  • 吸引更多的开发者参与和贡献
  • 更多的了解 Natasha 的实际使用场景,以便后续版本的计划

我们期待您能提供

在此提交一条评论, 评论内容包括:

您所在公司、学校或组织
您所在的城市、国家
您的联系方式: 微博、邮箱、微信 (至少一个)
您将 Natasha 用于哪些业务场景

可以参考下面的示例:

组织:nms
地点:**北京
联系方式: [email protected]
使用场景:基于 Natasha 打造开源项目.

多谢您的支持!
NCC Natasha 社区

hello world 失败

https://natasha.dotnetcore.xyz/zh-Hans/docs/get_started/getting-started
按这里所说 跑不起来 得到异常
找不到 RuntimeMetadataVersion 的值。找不到包含 System.Object 的程序集,或未通过选项为 RuntimeMetadataVersion 指定值。

我的代码 .net core 6

NatashaManagement.Preheating();
//你需要准备一个字符串
string script = "Console.WriteLine(\"Hello World!\");";
for (int i = 0; i < 10; i++)
{
    //      NDomain.Random().Delegate(script);  这个类没了    NatashaManagement.CreateRandomDomain() 没有 Action方法?.
    var action = NDelegate.RandomDomain().Action(script);
    action();
    //如果以后都不会再用 action 可以卸载
    action.DisposeDomain();
}

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/publish.yml
  • actions/checkout v3
  • actions/setup-dotnet v2
  • actions/setup-dotnet v2
  • actions/setup-dotnet v2
  • actions/setup-dotnet v2
nuget
Directory.Build.props
  • DotNetCore.SourceLink.Environment 3.2.0
samples/PluginSample/PluginA/PluginA.csproj
  • Dapper 2.0.123
samples/PluginSample/PluginB/PluginB.csproj
  • Dapper 1.60.6
samples/PluginSample/PluginBase/PluginBase.csproj
samples/PluginSample/PluginSample/PluginSample.csproj
  • Dapper 1.60.0
src/Natasha.CSharp/Extension/Natasha.CSharp.Extension.Ambiguity/Natasha.CSharp.Extension.Ambiguity.csproj
src/Natasha.CSharp/Natasha.CSharp/Natasha.CSharp.csproj
  • System.Reflection.MetadataLoadContext 7.0.0
  • Microsoft.Extensions.DependencyModel 7.0.0
  • System.Reflection.MetadataLoadContext 6.0.0
  • Microsoft.Extensions.DependencyModel 6.0.0
  • Microsoft.CodeAnalysis.CSharp.Workspaces 4.5.0
src/Natasha.Domain/Natasha.Domain.csproj

  • Check this box to trigger a request for Renovate to run again on this repository

不支持识别 static 、new static

parent class:

    public class T1
    {
        public static void A() { }
        public virtual void B() { }
        public virtual void C() { }
        public virtual void D() { }
        public void E() { }
    }

child class:

    public class T2 : T1
    {
        public new static void A() { }
        public override void B() { }
        public new virtual void C() { }
        public sealed override void D() { }
        public new void E() { }
    }

How do I decide whether a method is static or new static?

You get information by reflection, exactly the same thing ↓

image

See IL Code,same code:

.method public hidebysig static 
	void A () cil managed 

有动态编译的文档或示例吗?

有个使用 CodeDom 的项目,但是有个使用 dotnet cli 编译的问题 aspnet/RoslynCodeDomProvider#51 ,想试用一下 Natasha ,不知道是不是可以解决现在的问题,

有这样一个功能,根据源代码编译获取到一个Assembly,获取到里面定义的类型,可能需要支持引用指定的程序集,项目代码

        public static List<TableEntity> GeTableEntityFromSourceCode(params string[] sourceFilePaths)
        {
            if (sourceFilePaths == null || sourceFilePaths.Length <= 0)
            {
                return null;
            }
            var provider = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();

            var result = provider.CompileAssemblyFromFile(new CompilerParameters(
                new[]
                {
                    "System.dll",
                    "System.ComponentModel.DataAnnotations.dll",
                }),
                sourceFilePaths);
            if (result.Errors.HasErrors)
            {
                var error = new StringBuilder(result.Errors.Count * 1024);
                for (var i = 0; i < result.Errors.Count; i++)
                {
                    error.AppendLine($"{result.Errors[i].FileName}({result.Errors[i].Line},{result.Errors[i].Column}):{result.Errors[i].ErrorText}");
                }
                throw new ArgumentException($"所选文件编译有错误{Environment.NewLine}{error}");
            }
            var types = result.CompiledAssembly.GetTypes();
            // ...
        }

有一个小需求请教下

非常感谢您提供这么好的库!

现在我有一个需求,我想按照某个类的样子动态创建一个影子类,也就是类结构一模一样,但是 不是同一个类。(特别说明不是拷贝对象的意思),我想动态创建影子类放到动态创建的程序集中,程序启动时注入到应用中。

看起来有点像代理类。之前想通过castle.core做,但是没达到预想。

请问不同名的AssemblyDomain是不能相互访问内容么?

我将一些类放到了例如名"A"的AssemblyDomain
然后使用NDomain.Create("B").Action("脚本,脚本中使用了"A"中的类","A中的所有程序集的类型并转换为数组")
执行生成的Action时会提示空引用异常
我得知Natasha编译时抛出了找不到A中的类的异常.
我知道将NDomain.Create("B")中的B改为A会正常运行,这样的设计是为了方便卸载么?
代码如下:

using System;
using System.Linq;
using System.Text;
using Natasha;
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var assemblyDomain = new AssemblyDomain("A");
            var stringBuilder = new StringBuilder();
            stringBuilder.AppendLine(@"using System;");
            stringBuilder.AppendLine(@"namespace ClassLibrary1");
            stringBuilder.AppendLine(@"{");
            stringBuilder.AppendLine(@"public class Class1");
            stringBuilder.AppendLine(@"{");
            stringBuilder.AppendLine(@"public int I { get; set; }");
            stringBuilder.AppendLine(@"public override string ToString()");
            stringBuilder.AppendLine(@"{");
            stringBuilder.AppendLine(@"return $""{nameof(I)}: {I}"";");
            stringBuilder.AppendLine(@"}");
            stringBuilder.AppendLine(@"public static void T()");
            stringBuilder.AppendLine(@"{");
            stringBuilder.AppendLine(@"var random = new Random();");
            stringBuilder.AppendLine(@"var class1 = new Class1() {I = random.Next()};");
            stringBuilder.AppendLine(@"Console.WriteLine(class1);");
            stringBuilder.AppendLine(@"}");
            stringBuilder.AppendLine(@"}");
            stringBuilder.AppendLine(@"}");
            NAssembly assembly = assemblyDomain.CreateAssembly();
            assembly.AddScript(stringBuilder.ToString());
            assembly.Complier();
            NDomain.Create("B", ComplierResultError.ThrowException)
                .Action("Class1.T();",
                    assemblyDomain.Assemblies.SelectMany(x => x.GetTypes()).ToArray())
                .Invoke();
            Console.ReadKey();
        }
    }
}

抛出的异常

-----------------------------------------------error---------------------------------------------------

    Time :		2020-03-15 23:37:18

    Lauguage :	C# & CSharp8

    Target:		7b654560da464f17bc437e9767cf68bc

    Error:		共1处错误!
		第158行,第8个字符:       内容【Class1】  当前上下文中不存在名称“Class1”

====================================================================

NDelegate.Action发生异常!提示参数arg1不存在。

前置条件:
.Net6.0.100
DotNetCore.Natasha.CSharp (4.2.0)
DotNetCore.Compile.Environment (3.0.0)

发生异常!提示当前上下文中不存在名称arg1。
NDelegate.CreateDomain("TestCustomDelegate").Action<string>("Console.WriteLine(arg1);").Invoke("我是谁?");
执行正常。
NDelegate.CreateDomain("TestCustomDelegate").Action<string,string>("Console.WriteLine(arg1+\"-\"+arg2);").Invoke("我是谁?","我是靓仔");

泛型约束反解测试

这是从我的库抽取出来的,需要修改一下

using CZGL.CodeAnalysis;
using System;
using System.Collections;
using System.Collections.Generic;
using Xunit;
using Xunit.Abstractions;

namespace BaseTests
{
    public class Model_泛型1<T1, T2, T3>
    {

    }

    public class Model_泛型2<T1, T2, T3> : Model_泛型1<T1, T2, T3> where T1 : struct
    {

    }

    public class Model_泛型3 : Model_泛型1<int, double, int>
    {

    }


    public class Model_泛型类4 { }
    public class Model_泛型类5<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
        where T1 : struct
        where T2 : class
        where T3 : notnull
        where T4 : unmanaged
        where T5 : new()
        where T6 : Model_泛型类4
        where T7 : IEnumerable<int>
        where T8 : T2
        // 组合条件
        where T9 : class, new()
        where T10 : Model_泛型类4, IEnumerable<int>, new()
    {
    }

    public interface IModel1泛型类定义
    {

    }
    public class Model1_5 : Model_泛型1<int, double, int>, IEnumerable<object>, IModel1泛型类定义
    {
        public IEnumerator<object> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }

    public class 解析泛型类
    {
        ITestOutputHelper _tempOutput;
        public 解析泛型类(ITestOutputHelper tempOutput)
        {
            _tempOutput = tempOutput;
        }
        [Fact]
        public void 泛型类_未定义参数类型()
        {
            Type type = typeof(Model_泛型1<,,>);
            GenericeAnalysis genericeAnalysis = new GenericeAnalysis();
            var z = genericeAnalysis.Analysis(type);
            Assert.Equal("<, , >", genericeAnalysis.Analysis(type));
            Assert.Equal("<T1, T2, T3>", genericeAnalysis.Analysis(type, true));
        }

        [Fact]
        public void 泛型类_已定义参数类型()
        {
            Type type = typeof(Model_泛型1<int, double, int>);
            GenericeAnalysis genericeAnalysis = new GenericeAnalysis();
            Assert.Equal("<int, double, int>", genericeAnalysis.Analysis(type));
            Assert.Equal("<System.Int32, System.Double, System.Int32>", genericeAnalysis.Analysis(type, true));
        }

        //[Fact]
        //public void 泛型类_未定义参数_泛型父类解析()
        //{
        //    Type type = typeof(Model_泛型2<,,>);
        //    GenericeAnalysis genericeAnalysis = new GenericeAnalysis(type);
        //    Assert.Equal("<,,>", genericeAnalysis.BaseTypeAnalysis());
        //    Assert.Equal("<T1,T2,T3>", genericeAnalysis.Analysis(true));
        //}

        [Fact]
        public void 泛型类_泛型父类解析()
        {
            Model_泛型2<int, double, int> model_ = new Model_泛型2<int, double, int>();
            Type type = model_.GetType();
            GenericeAnalysis genericeAnalysis = new GenericeAnalysis();
            Assert.Equal("<int, double, int>", genericeAnalysis.Analysis(type.BaseType));
            Assert.Equal("<System.Int32, System.Double, System.Int32>", genericeAnalysis.Analysis(type.BaseType, true));
        }

        [Fact]
        public void 子类非泛型_父类泛型已定义解析()
        {
            Type type = new Model_泛型3().GetType();
            GenericeAnalysis genericeAnalysis = new GenericeAnalysis();
            Assert.Equal("<int, double, int>", genericeAnalysis.Analysis(type.BaseType));
            Assert.Equal("<System.Int32, System.Double, System.Int32>", genericeAnalysis.Analysis(type.BaseType, true));
        }

        [Fact]
        public void 长嵌套泛型参数解析()
        {
            Type type = typeof(Model_泛型1<int, List<int>, Dictionary<List<int>, Dictionary<int, List<int>>>>);
            GenericeAnalysis genericeAnalysis = new GenericeAnalysis();
            Assert.Equal("<int, List<int>, Dictionary<List<int>, Dictionary<int, List<int>>>>", genericeAnalysis.Analysis(type));
            Assert.Equal(@"<System.Int32, System.Collections.Generic.List<System.Int32>, System.Collections.Generic.Dictionary<System.Collections.Generic.List<System.Int32>, System.Collections.Generic.Dictionary<System.Int32, System.Collections.Generic.List<System.Int32>>>>", genericeAnalysis.Analysis(type, true));
        }

        [Fact]
        public void 超复杂的泛型约束()
        {
            Type type = typeof(Model_泛型类5<,,,,,,,,,,>);
            GenericeAnalysis genericeAnalysis = new GenericeAnalysis();
            _tempOutput.WriteLine(genericeAnalysis.GetGenericConstraintString(type));
            Assert.Equal(@"where T1 : struct 
where T2 : class 
where T3 : notnull 
where T4 : struct 
where T5 : new() 
where T6 : Model_泛型类4 
where T7 : IEnumerable<int> 
where T8 : T2 
where T9 : class,notnull,new() 
where T10 : Model_泛型类4,IEnumerable<int>,new() 
", genericeAnalysis.GetGenericConstraintString(type));
        }
    }
}

Natasha.Clone

使用Natasha的克隆扩展:
Example:

    Using : Natasha.Clone; 
    var instance = new ClassA();
    var result = instance.Clone();

image

    public static class CloneExtension
{
    public static T Clone<T>(this T instance) where T : Delegate
    {
        return CloneOperator.Clone(instance);
    }
}

ClassA 这个为什么 是委托,不是类。看了这个名字好奇怪

动态脚本,如何和宿主程序中的对象交互

public class Globals{ publicintX; publicintY;}
varglobals = newGlobals { X = 1, Y = 2};
Console.WriteLine(awaitCSharp.EvaluateAsync< int>( "X+Y", globals: globals));
如上,使用roslyn脚本中可以访问宿主程序中的对象,
那么使用natasha该如何实现呢,谢谢~

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.