Có cách nào để tạo thư viện .Net cho Windows và Mac, với các tham chiếu phụ thuộc vào nền tảng không?


12

Chúng tôi đang cố gắng phát triển một ứng dụng đa nền tảng cho máy tính để bàn (Windows và Mac) bằng C #. Ứng dụng chứa một lượng lớn nội dung phụ thuộc vào nền tảng và trưởng nhóm của chúng tôi muốn chúng tôi viết tất cả mã đó bằng C #. Cách dễ dàng để làm điều này là viết các trình bao bọc trong C ++ và chỉ cần tham khảo các thư viện trong mã C # và để các thư viện C ++ xử lý các công cụ nền tảng ... than ôi, không phải vậy.

Tôi đang cố gắng thiết lập một thư viện bằng Visual Studio cho Mac. Tôi hy vọng có thể cung cấp một giao diện duy nhất trong một thư viện để cấp quyền truy cập vào văn bản gốc cho thư viện lời nói trên nền tảng hiện tại - tốt nhất là không thực hiện hai cụm. Thư viện chuyển văn bản thành giọng nói trong C # cho Windows không khả dụng trên Mac, vì vậy chúng tôi thực sự không có lựa chọn nào khác ngoài việc tự cung cấp một số cầu nối.

Tôi rất vui khi thư viện thực hiện tra cứu hệ điều hành để xác định hệ điều hành nào nó đang chạy và / hoặc cố tải một loạt các thư viện riêng và chỉ sử dụng thư viện nào sẽ tải.

Nếu tôi phải, có một dự án duy nhất cho phép tôi viết hai triển khai sẽ phải làm. Tôi chưa tìm thấy cách tạo dự án thư viện trong Visual Studio cho Mac, tuy nhiên điều đó sẽ cho phép tôi làm như vậy. Loại dự án duy nhất sẽ cho phép nhiều triển khai dường như yêu cầu các triển khai đó dành cho iOS hoặc cho Android.


Thời gian chạy .NET nào bạn sẽ sử dụng?
Euphoric

2
Xamarin làm điều gì đó tương tự. Có lẽ với cấu hình xây dựng?
Ewan

2
Đáng chú ý là Visual Studio cho mac không thực sự là studio trực quan, Nó chỉ là một studio Xamarin nổi loạn. Có lẽ có một cái gì đó trong các tài liệu Xamarin?
richzilla

3
Cách tiếp cận tốt nhất sẽ là các hội đồng khác nhau ... Một cho các giao diện và mã chung và một cho các nền tảng đích. Tuy nhiên, bạn có thể đa mục tiêu và sử dụng các câu lệnh #if để trao đổi các triển khai. Nhược điểm là bất cứ thứ gì không được kích hoạt đều không được đánh giá để có thể dễ dàng bị lỗi thời.
Berin Loritsch

Khi bạn nói các tham chiếu phụ thuộc nền tảng, bạn đang nói mã gốc hay tất cả mã C #?
Berin Loritsch

Câu trả lời:


4

Bạn có một câu hỏi hay. Có lẽ có một số đánh đổi với giải pháp của bạn. Câu trả lời cuối cùng thực sự phụ thuộc vào ý của bạn khi phụ thuộc vào nền tảng. Ví dụ: nếu bạn đang bắt đầu một quy trình để khởi động các ứng dụng bên ngoài và bạn chỉ cần chuyển đổi giữa ứng dụng này sang ứng dụng khác, bạn có thể có thể xử lý việc đó mà không gặp quá nhiều phức tạp. Nếu bạn đang nói P / Gọi với các thư viện riêng, thì sẽ còn một chút nữa phải làm. Tuy nhiên, nếu bạn đang liên kết với các thư viện chỉ tồn tại trên một nền tảng, có lẽ bạn sẽ cần phải sử dụng nhiều tập hợp.

Ứng dụng bên ngoài

Bạn có thể sẽ không cần phải sử dụng #ifbáo cáo trong tình huống này. Chỉ cần thiết lập một số giao diện và có một triển khai trên mỗi nền tảng. Sử dụng một nhà máy để phát hiện nền tảng và cung cấp ví dụ phù hợp.

Trong một số trường hợp, nó chỉ là một tệp nhị phân được biên dịch cho một nền tảng cụ thể nhưng tên của tệp thực thi và tất cả các tham số được xác định giống nhau. Trong trường hợp đó, đó là vấn đề giải quyết quyền thực thi. Đối với một ứng dụng chuyển đổi âm thanh hàng loạt có thể chạy trên Windows và Linux, tôi đã có một trình khởi tạo tĩnh giải quyết tên nhị phân.

public class AudioProcessor
{
    private static readonly string AppName = "lame";
    private static readonly string FullAppPath;

    static AudioProcessor()
    {
        var platform = DetectPlatform();
        var architecture = Detect64or32Bits();

        FullAppPath = Path.combine(platform, architecture, AppName);
    }
}

Không có gì lạ mắt ở đây. Chỉ là những lớp học thời trang tốt.

P / Gọi

P / Gọi là một chút phức tạp hơn. Điểm mấu chốt là bạn cần đảm bảo tải đúng phiên bản của thư viện gốc. Trên cửa sổ, bạn sẽ P / Gọi SetDllDirectory(). Các nền tảng khác nhau có thể không cần bước đó. Vì vậy, đây là nơi mọi thứ có thể trở nên lộn xộn. Bạn có thể cần sử dụng các #ifcâu lệnh để kiểm soát cuộc gọi nào được sử dụng để kiểm soát việc giải quyết đường dẫn thư viện của bạn - đặc biệt nếu bạn đưa nó vào gói phân phối.

Liên kết đến các thư viện phụ thuộc nền tảng hoàn toàn khác nhau

Cách tiếp cận đa mục tiêu của trường học cũ có thể hữu ích ở đây. Tuy nhiên, nó đi kèm với rất nhiều xấu xí. Trong những ngày mà một số dự án cố gắng có cùng mục tiêu DLL Silverlight, WPF và có khả năng UAP, bạn sẽ phải biên dịch ứng dụng nhiều lần với các thẻ biên dịch khác nhau. Thách thức với mỗi nền tảng ở trên là trong khi chúng có chung các khái niệm, các nền tảng đủ khác nhau mà bạn phải làm việc xung quanh những khác biệt đó. Đây là nơi chúng ta nhận được vào địa ngục #if.

Cách tiếp cận này cũng yêu cầu chỉnh sửa .csprojtập tin để xử lý các tham chiếu phụ thuộc vào nền tảng. Vì .csprojtệp của bạn là tệp MSBuild, nên hoàn toàn có thể thực hiện theo cách đã biết và có thể dự đoán được.

#if địa ngục

Bạn có thể bật và tắt các phần của mã bằng cách sử dụng các #ifcâu lệnh để có hiệu quả trong việc xử lý các khác biệt nhỏ giữa các ứng dụng. Nhìn bề ngoài có vẻ như là một ý tưởng tốt. Tôi thậm chí đã sử dụng nó như một phương tiện để bật và tắt trực quan hóa hộp giới hạn để gỡ lỗi mã vẽ.

Vấn đề số 1 với #ifkhông có mã nào bị tắt được đánh giá bởi trình phân tích cú pháp. Bạn có thể có lỗi cú pháp tiềm ẩn hoặc tệ hơn là lỗi logic đang chờ bạn biên dịch lại thư viện. Điều này càng trở nên rắc rối hơn với mã tái cấu trúc. Một cái gì đó đơn giản như đổi tên một phương thức hoặc thay đổi thứ tự các tham số thường sẽ được xử lý OK, nhưng vì trình phân tích cú pháp không bao giờ đánh giá bất cứ điều gì bị tắt bởi #ifcâu lệnh mà bạn đột nhiên bị hỏng mã mà bạn sẽ không thấy cho đến khi bạn biên dịch lại.

Tất cả các mã gỡ lỗi của tôi được viết theo cách đó phải được viết lại sau khi một loạt các phép tái cấu trúc đã phá vỡ nó. Trong quá trình viết lại, tôi đã sử dụng một lớp cấu hình toàn cầu để bật và tắt các tính năng đó. Điều đó làm cho nó tái cấu trúc công cụ bằng chứng, nhưng một giải pháp như vậy không giúp ích gì khi API hoàn toàn khác.

Phương pháp ưa thích của tôi

Phương pháp ưa thích của tôi, dựa trên nhiều bài học đau đớn đã học và thậm chí dựa trên ví dụ của chính Microsoft, là sử dụng nhiều tổ hợp.

Tập hợp NetSt Chuẩn một lõi sẽ xác định tất cả các giao diện và chứa tất cả các mã chung. Việc triển khai phụ thuộc nền tảng sẽ nằm trong một hội đồng riêng biệt sẽ thêm các tính năng khi được bao gồm.

Cách tiếp cận này được minh họa bằng API cấu hình mới và kiến ​​trúc Nhận dạng hiện tại. Khi bạn cần tích hợp cụ thể hơn, bạn chỉ cần thêm các cụm mới đó. Những hội đồng này cũng cung cấp các chức năng mở rộng để kết hợp chính nó vào thiết lập của bạn. Nếu bạn đang sử dụng phương pháp tiêm phụ thuộc, các phương thức mở rộng đó cho phép thư viện đăng ký các dịch vụ của nó.

Đây là cách duy nhất tôi biết để tránh #ifđịa ngục và thỏa mãn một môi trường khác biệt đáng kể.


Tôi hút tại C # (thiên đường đã sử dụng C ++ trong khoảng 18 năm và C # trong khoảng nửa ngày, đó là điều được mong đợi). Api cấu hình mới này ... bạn có thể cung cấp một số liên kết đến đó. Tôi dường như không thể tự tìm thấy nó.
Rõ ràng hơn

2
docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/ Khăn Có nhiều gói Nuget để thêm các nguồn cấu hình bổ sung. Ví dụ: từ các biến môi trường, tệp JSON, v.v.
Berin Loritsch

1
Đó là Microsoft.Extensions.Configurationbộ API.
Berin Loritsch

1
Đây là dự án github gốc: github.com/aspnet/Configuration
Berin Loritsch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.