Chuyển đến nội dung chính

Tạo Project Dependency graph cho dự án

Bạn đang phát triển một dự án .NET lớn và muốn trực quan hóa các phụ thuộc giữa các project con? UML là một công cụ tuyệt vời để tạo sơ đồ UML đơn giản chỉ bằng text

Dưới đây là 2 đoạn mã minh họa bằng Powershell và C#

PowerShell

Đây là đoạn code gốc được viết bằng PowerShell trên https://blog.dantup.com/2012/05/free-dependency-graph-generation-using-powershell-and-yuml/:
function Get-ProjectReferences
{
    param(
        [Parameter(Mandatory)]
        [string]$rootFolder,
        [string[]]$excludeProjectsContaining
    )
    dir $rootFolder -Filter *.csproj -Recurse |
        # Exclude any files matching our rules
        where { $excludeProjectsContaining -notlike "*$($_.BaseName)*" } |
        Select-References
}
function Select-References
{
    param(
        [Parameter(ValueFromPipeline, Mandatory)]
        [System.IO.FileInfo]$project,
        [string[]]$excludeProjectsContaining
    )
    process
    {
        $projectName = $_.BaseName
        [xml]$projectXml = Get-Content $_.FullName
        $ns = @{ defaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003" }
        $projectXml |
            # Find the references xml nodes
            Select-Xml '//defaultNamespace:ProjectReference/defaultNamespace:Name' -Namespace $ns |
            # Get the node values
            foreach { $_.node.InnerText } |
            # Exclude any references pointing to projects that match our rules
            where { $excludeProjectsContaining -notlike "*$_*" } |
            # Output in yuml.me format
            foreach { "[" + $projectName + "] -> [" + $_ + "]" }
    }
}
$excludedProjects = "Test1", "Test2"
Get-ProjectReferences "C:\Users\DanTup\Documents\MyProject" -excludeProjectsContaining $excludedProjects | Out-File "C:\Users\DanTup\Documents\MyProject\References.txt"

C#

Đoạn code dưới đây được bổ sung thêm parameter relatedProject. Trường hợp Solution nhiều project, bạn chỉ muốn hiển thị những project references liên quan tới project bạn cần xem thì bạn set giá trị cho biến này
// See https://aka.ms/new-console-template for more information
using System.Xml.Linq;

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

var rootFolder = @"D:\Projects\YourProject";
string[] excludedProjects = { "Test" };
var outputFile = @"D:\Practices\UML\References.txt";

var relatedProject = "Validation";

var dependencies = GetProjectReferences(rootFolder, excludedProjects, relatedProject);

File.WriteAllLines(outputFile, dependencies);
Console.WriteLine("Dependencies written to " + outputFile);

static List<string> GetProjectReferences(string rootFolder, string[] excludedProjects, string relatedProject)
{
    return Directory.EnumerateFiles(rootFolder, "*.csproj", SearchOption.AllDirectories)
        .Where(file => !excludedProjects.Any(p => file.Contains(p)))
        .SelectMany(file => SelectReferences(file, excludedProjects, relatedProject)) // Pass excludedProjects
        .ToList();
}

static List<string> SelectReferences(string projectFile, string[] excludedProjects, string relatedProject) // Add excludedProjects parameter
{
    var msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
    var projectName = Path.GetFileNameWithoutExtension(projectFile);
    XDocument projectXml = XDocument.Load(projectFile);
    var projectXmlString = projectXml.ToString();

    if (projectXml.ToString().Contains(msbuild)){
        projectXml = XDocument.Parse(projectXmlString.Replace(msbuild, string.Empty));
    }

    var projectReferenceElements = projectXml.Descendants("ProjectReference").ToList();

    var references = projectReferenceElements
        .Select(r =>
        {
            string referenceName = r.Element("Name")?.Value;
            if (string.IsNullOrEmpty(referenceName))
            {
                // Extract name from Include attribute if Name is missing
                referenceName = r.Attribute("Include")?.Value.Split('\\').Last();
            }
            return referenceName;
        })
        .Where(name => !excludedProjects.Any(p => name.Contains(p)))
        .Select(name => $"[{projectName}] -> [{name}]").ToList();

    references = references.Where(t=>t.Contains(relatedProject)).ToList();

    foreach (var testElement in references)
    {
        Console.WriteLine(testElement);
    }
    return references;
}

Giải thích

  • Đoạn code duyệt qua tất cả các file .csproj trong thư mục gốc và các thư mục con.
  • Nó lọc các dự án được liệt kê trong excludedProjects.
  • Đối với mỗi file .csproj, chương trình trích xuất tên project và các project tham chiếu.
  • Cuối cùng, chương trình ghi các mối quan hệ dự án dưới dạng văn bản UML vào file outputFile.
Ví dụ:
[A] -> [Validation]
[B] -> [Validation]
[Validation] -> [C]
[Validation] -> [C1]
Sử dụng trang https://yuml.me/diagram/scruffy/class/draw hoặc https://plantuml-editor.kkeisuke.com/ để hiển thị UML online

Tham khảo

Free dependency graph generation using PowerShell and yUML

Nhận xét

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.