欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于Metalama使用Fabric操作項(xiàng)目或命名空間的問(wèn)題

 更新時(shí)間:2022年04月24日 09:48:13   作者:重典  
Metalama是一個(gè)基于微軟編譯器Roslyn的元編程的庫(kù),可以解決我在開(kāi)發(fā)中遇到的重復(fù)代碼的問(wèn)題,這篇文章主要介紹了Metalama使用Fabric操作項(xiàng)目或命名空間,需要的朋友可以參考下

Metalama中的Fabric可以做什么

Metalama是一個(gè)基于微軟編譯器Roslyn的元編程的庫(kù),可以解決我在開(kāi)發(fā)中遇到的重復(fù)代碼的問(wèn)題。但是其實(shí)Metalama不止可以提供編譯時(shí)的代碼轉(zhuǎn)換,更可以提供自定義代碼分析、與IDE結(jié)合的自定義代碼修復(fù)與代碼重構(gòu)功能 等功能。

經(jīng)過(guò)面對(duì)文檔的學(xué)習(xí),發(fā)現(xiàn)Metalama可以做到很多非常神奇的事情。

Fabric通過(guò)修改項(xiàng)目、命名空間、類(lèi)型來(lái)達(dá)到一些效果,這引起修改包括:添加Aspect或添加代碼分析

使用Fabric為指定的方法添加Aspect

前文中我們寫(xiě)過(guò)一個(gè)簡(jiǎn)單的Aspect:

public class LogAttribute : OverrideMethodAspect
{
    public override dynamic? OverrideMethod()
    {
        Console.WriteLine(meta.Target.Method.ToDisplayString() + " 開(kāi)始運(yùn)行.");
        var result = meta.Proceed();
        Console.WriteLine(meta.Target.Method.ToDisplayString() + " 結(jié)束運(yùn)行.");
        return result;
    }
}

當(dāng)我們使用它時(shí),我們要在對(duì)應(yīng)的方法上添加這個(gè)Attribute:

[Log]
private static int Add(int a, int b) //... ...

那么當(dāng)我們有一個(gè)Aspect要在項(xiàng)目中大量使用時(shí),在每個(gè)方法上添加這個(gè)Aspect當(dāng)然是一種方法,但是這種方法有2個(gè)缺點(diǎn):

  • 包含大量的重復(fù)代碼[Log]
  • 對(duì)于原代碼的入侵性太強(qiáng)

此時(shí)我們就可以使用Fabric為所有符合要求的方法添加指定的Aspect:

internal class Fabric : ProjectFabric
{
    // 這個(gè)是重寫(xiě)項(xiàng)目的Fabric中修改項(xiàng)目的方法
    public override void AmendProject(IProjectAmender amender)
    {
        // 添加 LogAttribute 到符合規(guī)則的方法上
        // 為名為 Add 且 private 的方法添加 LogAttribute
        amender.WithTargetMembers(c =>
                c.Types.SelectMany(t => t.Methods)
                       .Where(t =>
                              t.Name == "Add" &&
                              t.Accessibility == Metalama.Framework.Code.Accessibility.Private)
            ).AddAspect(t => new LogAttribute());
    }
}

 

這樣就可以在不入侵現(xiàn)有代碼的情況下為指定的方法添加Aspect。

使用Fabric添加代碼分析

上文中我們提到,我們可以通過(guò)Aspect為代碼添加代碼分析,當(dāng)我們要將一個(gè)包含(且僅包含)代碼分析的Aspect應(yīng)用于一批代碼時(shí),當(dāng)然我們可以按本文示例1中的方法,直接使用Fabric將包含代碼分析的Aspect應(yīng)用于指定代碼。

但還有另外一種方法,我們可以直接在Fabric中定義應(yīng)用于指定代碼的代碼分析。

下面示例,我們驗(yàn)證所有類(lèi)中的私有字段必須符合 _camelCase,并且使用一個(gè)NamespaceFabric來(lái)實(shí)現(xiàn):

namespace FabricCamelCaseDemo;
class Fabric : NamespaceFabric
{
    private static readonly DiagnosticDefinition<string> _warning = new(
 "DEMO04",
 Severity.Warning,
 "'{0}'必須使用駝峰命名法并以'_'開(kāi)頭");
    // 這個(gè)是命名空間的Fabric中修改命名空間規(guī)則 的方法
    public override void AmendNamespace(INamespaceAmender amender)
    {
	    // 取所有非static 的private的字段,并添加代碼分析
        amender.WithTargetMembers(c =>
                                    c.AllTypes.SelectMany(t=>t.Fields)
                                    .Where(t => t.Accessibility == Accessibility.Private && !t.IsStatic
                                    )
                                 )
            //preview 0.5.8之前為 RegisterFinalValidator
            .Validate(this.FinalValidator);
    }
 
    private void FinalValidator(in DeclarationValidationContext context)
    {
        var fullname = context.Declaration.ToDisplayString();
        var fieldName = fullname.Split('.').LastOrDefault();
        if (fieldName!=null && (!fieldName.StartsWith("_") || !char.IsLower(fieldName[1])))
        {
            context.Diagnostics.Report(_warning.WithArguments(fieldName));
        }
    }
}

image

當(dāng)然因?yàn)楫?dāng)前使用的是NamespaceFabric所以該規(guī)則只應(yīng)用于當(dāng)前命名空間如,我們?nèi)绻诹硗庖粋€(gè)命名空間中定義一個(gè)違反規(guī)則的字段的話(huà),并不會(huì)有警告。

namespace FabricCamelCase;
internal class OtherNamespace
{
    int count = 0;
    int _total = 0;
    public int Add()
    {
        count++;
        _total++;
        return count + _total;
    }
}

使用TypeFabric為類(lèi)型動(dòng)態(tài)添加方法

開(kāi)始前偽造一個(gè)需求,假設(shè)我有一個(gè)類(lèi)AddUtils專(zhuān)門(mén)處理加法操作,它里面應(yīng)該有從2個(gè)到15個(gè)參數(shù)的Add方法15個(gè)(當(dāng)然我知道,可以使用params等方法實(shí)現(xiàn),所以這里是個(gè)偽需求)。
最終效果為

public class AddUtils
{
    public int Add2(int x1, int x2)
    {
        var result = 0;
        result += x1;
        result += x2;
        return 2;
    }
    public int Add3(int x1, int x2, int x3)
    {
        var result = 0;
        result += x1;
        result += x2;
        result += x3;
        return 3;
    }
	// 以此類(lèi)推... 下面省去若干方法
}

那么我們可以用Metalama如此實(shí)現(xiàn)

using System.Reflection.Emit;
using Metalama.Framework.Aspects;
using Metalama.Framework.Fabrics;
 
public class AddUtils
{
    private class Fabric : TypeFabric
    {
        // 實(shí)現(xiàn)的方法體
        [Template]
        public int MethodTemplate()
        {
            var num = (int) meta.Tags["nums"]!;
            var result = 0;
            foreach (var targetParameter in meta.Target.Parameters)
            {
                result += targetParameter.Value;
            }
            return num;
        }
        public override void AmendType(ITypeAmender amender)
            for (var i = 2; i < 15; i++)
                // 生成一個(gè)方法
                var methodBuilder = amender.Advices.IntroduceMethod(
                    amender.Type,
                    nameof(this.MethodTemplate),
                    tags: new TagDictionary { ["nums"] = i });
                // 方法名
                methodBuilder.Name = "Add" + i;
                // 添加參數(shù)
                for (int parameterIndex = 1; parameterIndex <= i; parameterIndex++)
                {
                    methodBuilder.AddParameter($"x{parameterIndex}", typeof(int));
                }
    }
}

引用

本章源代碼:https://github.com/chsword/metalama-demo

Metalama官方文檔: https://doc.metalama.net/

Metalama Nuget包: https://www.nuget.org/packages/Metalama.Framework/0.5.11-preview

到此這篇關(guān)于Metalama使用Fabric操作項(xiàng)目或命名空間的文章就介紹到這了,更多相關(guān)Metalama操作項(xiàng)目或命名空間內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ASP.NET操作各類(lèi)時(shí)間段獲取方法匯總

    ASP.NET操作各類(lèi)時(shí)間段獲取方法匯總

    這篇文章主要介紹了ASP.NET操作各類(lèi)時(shí)間段獲取方法,實(shí)例匯總了各類(lèi)常見(jiàn)的時(shí)間段獲取方法,需要的朋友可以參考下
    2014-11-11
  • Asp.Net Core利用文件監(jiān)視進(jìn)行快速測(cè)試開(kāi)發(fā)詳解

    Asp.Net Core利用文件監(jiān)視進(jìn)行快速測(cè)試開(kāi)發(fā)詳解

    這篇文章主要給大家介紹了關(guān)于Asp.Net Core利用文件監(jiān)視進(jìn)行快速測(cè)試開(kāi)發(fā)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • .NET Core中創(chuàng)建和使用NuGet包的示例代碼

    .NET Core中創(chuàng)建和使用NuGet包的示例代碼

    這篇文章主要介紹了.NET Core中創(chuàng)建和使用NuGet包的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)中篇

    ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)中篇

    這篇文章主要為大家再一次介紹了ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 使用 ServiceStack.Text 序列化 json的實(shí)現(xiàn)代碼

    使用 ServiceStack.Text 序列化 json的實(shí)現(xiàn)代碼

    今天發(fā)篇文章總結(jié)下自己使用 ServiceStack.Text 來(lái)序列化 json。它的速度比 Newtonsoft.Json 快很多,在測(cè)試時(shí)發(fā)現(xiàn)比 fastJson 還快些
    2013-06-06
  • ASP.NET MVC5網(wǎng)站開(kāi)發(fā)之登錄、驗(yàn)證和注銷(xiāo)管理員篇1(六)

    ASP.NET MVC5網(wǎng)站開(kāi)發(fā)之登錄、驗(yàn)證和注銷(xiāo)管理員篇1(六)

    這篇文章主要介紹了ASP.NET MVC5網(wǎng)站開(kāi)發(fā)之管理員登錄、驗(yàn)證和注銷(xiāo),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • ASP.NET使用正則表達(dá)式屏蔽垃圾信息

    ASP.NET使用正則表達(dá)式屏蔽垃圾信息

    找資料,看看如何實(shí)現(xiàn)使用正則表達(dá)式屏蔽垃圾信息,找來(lái)找去找出來(lái)的都不怎么好,有不詳細(xì)的,有代碼缺失的。最后還是找到了微軟,先摘過(guò)來(lái),大概思路已經(jīng)有了,只需把下面微軟給的樣例代碼修改一下即可,具體能不能行還不知道,先睡一覺(jué),起來(lái)再慢慢研究。
    2008-09-09
  • ASP.NETCore6開(kāi)啟文件服務(wù)允許通過(guò)url訪(fǎng)問(wèn)附件的操作方法

    ASP.NETCore6開(kāi)啟文件服務(wù)允許通過(guò)url訪(fǎng)問(wèn)附件的操作方法

    最近在做一個(gè)工作臺(tái)的文件上傳下載功能,主要想實(shí)現(xiàn)上傳圖片之后,可以通過(guò)url直接訪(fǎng)問(wèn),由于url直接訪(fǎng)問(wèn)文件不安全,所以需要手動(dòng)開(kāi)啟文件服務(wù),這篇文章主要介紹了ASP.NETCore6開(kāi)啟文件服務(wù)允許通過(guò)url訪(fǎng)問(wèn)附件,需要的朋友可以參考下
    2023-11-11
  • WPF使用VisualTreeHelper進(jìn)行命中測(cè)試

    WPF使用VisualTreeHelper進(jìn)行命中測(cè)試

    這篇文章介紹了WPF使用VisualTreeHelper進(jìn)行命中測(cè)試的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 異步 HttpContext.Current實(shí)現(xiàn)取值的方法(解決異步Application,Session,Cache...等失效的問(wèn)題)

    異步 HttpContext.Current實(shí)現(xiàn)取值的方法(解決異步Application,Session,Cache.

    在一個(gè)項(xiàng)目中,為了系統(tǒng)執(zhí)行效率更快,把一個(gè)經(jīng)常用到的數(shù)據(jù)庫(kù)表通過(guò)dataset放到Application中,發(fā)現(xiàn)在異步實(shí)現(xiàn)中每一次都會(huì)出現(xiàn)HttpContext.Current為null的異常,后來(lái)在網(wǎng)上查了好多資料,發(fā)現(xiàn)問(wèn)這個(gè)問(wèn)題的人多,回答的少
    2009-07-07

最新評(píng)論