فرض کنید اسمبلی A که System.Drawing.Common، نام دارد، فضای نام System.Drawing.Common را ارائه میدهد و اسمبلی B که CoreCompact.System.Drawing نام دارد، باز هم دقیقا همان فضای نام را ارائه میدهد. سؤال: آیا میتوان از این دو اسمبلی مختلف در برنامهی خود استفاده کرد؟ یا مثال دیگر آن داشتن دو اسمبلی با نگارشهای مختلف، از یک کتابخانه است. برای مثال یکی بر اساس netcoreapp2.1 تهیه شدهاست و دیگری بر اساس netstandard2.0 و به هر دلیلی نیاز است که بتوان از هر دو اسمبلی در برنامهی خود استفاده کرد. برای یک چنین مواردی در زبان #C ویژگی به نام extern alias وجود دارد که با مثالی نحوهی کار با آنرا بررسی خواهیم کرد.
ایجاد پروژهی Globe1
پروژهی کتابخانهی Globe1 را بر اساس netcoreapp2.1 به این صورت توسط فایلهای زیر ایجاد میکنیم:
الف) فایل Globe1.csproj
ب) فایل Globe.cs
ایجاد پروژهی Globe2
پروژهی کتابخانهی Globe2 را بر اساس netstandard2.0 به این صورت توسط فایلهای زیر ایجاد میکنیم:
الف) فایل Globe2.csproj
ب) فایل Globe.cs
ایجاد یک پروژهی کنسول استفاده کنندهی از این اسمبلیها
همانطور که ملاحظه میکنید اگر این دو پروژهی class library را کامپایل کنیم، به دو فایل dll یا اسمبلی خواهیم رسید که هر دو دارای فضای نام Space و همچنین کلاس Globe هستند. اما نگارشهای آنها و یا TargetFrameworkهای آنها متفاوت است. اکنون میخواهیم از هر دوی اینها در یک پروژهی Console استفاده کنیم. بنابراین ابتدا این پروژه را با ایجاد فایل csproj آن شروع میکنیم:
الف) فایل Owl.csproj
روش ارجاع دهی به این اسمبلیها، اندکی متفاوت است. در اینجا نام هر کدام به همراه شماره نگارش آنها ذکر شدهاست. همچنین مسیر یافتن فایلهای Globe1.dll و Globe2.dll نیز ذکر شدهاند؛ بجای اینکه ارجاعی را به فایلهای csproj این class libraryها اضافه کنیم (از این جهت که ممکن است مانند مثال ابتدای بحث، صرفا دو فایل dll را بیشتر در اختیار نداشته باشیم). به علاوه یک Alias نیز برای هر کدام تعریف شدهاست تا توسط آن بتوان به امکانات هرکدام دسترسی یافت. وجود این Alias از این جهت ضروری است که هرچند دو فایل dll مختلف را داریم، اما فضاهای نام و کلاسهای آنها، نامهای مشابهی دارند و قابل تمیز از یکدیگر نیستند.
ب) فایل Program.cs
اکنون قسمت مهم این فایل، همان extern aliasهایی هستند که پیشتر تعریف کردیم:
ابتدا extern aliasها تعریف میشوند:
سپس بر اساس هر Alias میتوان یک فضای نام جدید را بجای فضای نام Space فعلی هرکدام تعریف کرد:
تا بتوان به متدهای GetColor متفاوت اینها دسترسی یافت.
اگر این برنامه را اجرا کنیم، چنین خروجی حاصل میشود:
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید: alias.zip
ایجاد پروژهی Globe1
پروژهی کتابخانهی Globe1 را بر اساس netcoreapp2.1 به این صورت توسط فایلهای زیر ایجاد میکنیم:
الف) فایل Globe1.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> </PropertyGroup> </Project>
ب) فایل Globe.cs
using System; namespace Space { public class Globe { public string GetColor() => "Blue"; } }
ایجاد پروژهی Globe2
پروژهی کتابخانهی Globe2 را بر اساس netstandard2.0 به این صورت توسط فایلهای زیر ایجاد میکنیم:
الف) فایل Globe2.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> </Project>
ب) فایل Globe.cs
using System; namespace Space { public class Globe { public string GetColor() => "Green"; } }
ایجاد یک پروژهی کنسول استفاده کنندهی از این اسمبلیها
همانطور که ملاحظه میکنید اگر این دو پروژهی class library را کامپایل کنیم، به دو فایل dll یا اسمبلی خواهیم رسید که هر دو دارای فضای نام Space و همچنین کلاس Globe هستند. اما نگارشهای آنها و یا TargetFrameworkهای آنها متفاوت است. اکنون میخواهیم از هر دوی اینها در یک پروژهی Console استفاده کنیم. بنابراین ابتدا این پروژه را با ایجاد فایل csproj آن شروع میکنیم:
الف) فایل Owl.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.1</TargetFramework> </PropertyGroup> <ItemGroup> <Reference Include="Globe1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> <HintPath>..\Globe1\bin\$(Configuration)\netcoreapp2.1\Globe1.dll</HintPath> <Aliases>Lib1</Aliases> </Reference> <Reference Include="Globe2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> <HintPath>..\Globe2\bin\$(Configuration)\netstandard2.0\Globe2.dll</HintPath> <Aliases>Lib2</Aliases> </Reference> </ItemGroup> </Project>
ب) فایل Program.cs
اکنون قسمت مهم این فایل، همان extern aliasهایی هستند که پیشتر تعریف کردیم:
extern alias Lib1; extern alias Lib2; using System; using SpaceOne = Lib1::Space; using SpaceTwo = Lib2::Space; namespace Owl { class Program { static void Main(string[] args) { var owl = new SuperOwl(); owl.IntegrateGlobe(new SpaceOne.Globe()); owl.IntegrateGlobe(new SpaceTwo.Globe()); Console.WriteLine(owl.GetGLobeColors()); } } public class SuperOwl { private SpaceOne.Globe _firstGlobe; private SpaceTwo.Globe _secondGlobe; public void IntegrateGlobe(SpaceOne.Globe globe) => _firstGlobe = globe; public void IntegrateGlobe(SpaceTwo.Globe globe) => _secondGlobe = globe; public string GetGLobeColors() => $"First: {_firstGlobe.GetColor()}, Second: {_secondGlobe.GetColor()}"; } }
extern alias Lib1; extern alias Lib2;
using SpaceOne = Lib1::Space; using SpaceTwo = Lib2::Space;
اگر این برنامه را اجرا کنیم، چنین خروجی حاصل میشود:
First: Blue, Second: Green
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید: alias.zip