پروژه ویراستار را از Ruby به سی شارپ تبدیل کردم. سورس نهایی کامل، فایلهای باینری، به همراه unit tests و راهنمای کتابخانه، از آدرس زیر قابل دریافت هستند:
خلاصه کارهایی را که انجام میدهد:
"scripts": { "postcompile": [ "dotnet pack --no-build --configuration %compile:Configuration%" ] }
{ "version": "1.1.1.0", "authors": [ "Vahid Nasiri" ], "packOptions": { "owners": [ "Vahid Nasiri" ], "tags": [ "PdfReport", "Excel", "Export", "iTextSharp", "PDF", "Report", "Reporting", "Persian", ".NET Core" ], "licenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html", "projectUrl": "https://github.com/VahidN/iTextSharp.LGPLv2.Core" }, "description": " iTextSharp.LGPLv2.Core is an unofficial port of the last LGPL version of the iTextSharp (V4.1.6) to .NET Core.", "scripts": { "postcompile": [ "dotnet pack --no-build --configuration %compile:Configuration%" ] } }
"configurations": { "Release": { "buildOptions": { "optimize": true, "platform": "anycpu" } } },
"buildOptions": { "xmlDoc": true },
"buildOptions": { "xmlDoc": true, "nowarn": [ "1591" ] // 1591: missing xml comment for publicly visible type or member },
Scaffold CustomTemplate Name Template
Scaffold CustomTemplate View Index
[DisplayName("Due Date")] public DateTime? DueDate { set; get; }
// Describes the information about a property on the model class ModelProperty { public string Name { get; set; } public string DisplayName { get; set; } public string ValueExpression { get; set; } public EnvDTE.CodeTypeRef Type { get; set; } public bool IsPrimaryKey { get; set; } public bool IsForeignKey { get; set; } public bool IsReadOnly { get; set; } }
static string GetDisplayName(EnvDTE.CodeProperty prop) { var displayAttr = prop.Attributes.OfType<EnvDTE80.CodeAttribute2>().Where(x => x.FullName == typeof(System.ComponentModel.DisplayNameAttribute).FullName).FirstOrDefault(); if(displayAttr == null) { return prop.Name; } return displayAttr.Value.Replace("\"",""); }
results.Add(new ModelProperty { Name = prop.Name, DisplayName = GetDisplayName(prop), ValueExpression = "Model." + prop.Name, Type = prop.Type, IsPrimaryKey = Model.PrimaryKeyName == prop.Name, IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), IsReadOnly = !prop.IsWriteable() });
<# List<ModelProperty> properties = GetModelProperties(Model.ViewDataType, true); foreach (ModelProperty property in properties) { if (!property.IsPrimaryKey && !property.IsForeignKey) { #> <th> <#= property.DisplayName #> </th> <# } } #>
PM> Scaffold Controller -ModelType Task -ControllerName TasksController -DbContextType TasksDbContext -Repository -Force
PM> Scaffold CustomTemplate Controller ControllerWithRepository
// If you are using Dependency Injection, you can delete the following constructor public <#= Model.ControllerName #>() : this(<#= String.Join(", ", Repositories.Values.Select(x => "new " + x.RepositoryTypeName + "()")) #>) { }
PM> Scaffold Controller -ModelType Task -ControllerName TasksController -DbContextType TasksDbContext -Repository -Force -ForceMode ControllerOnly
Scaffold CustomScaffolder EFRepository
Dart کتابخانه ای است که توسط شرکت گوگل ارائه شده است و گفته میشود، قرار است جایگزین جاوا اسکریپت گردد و از آدرس https://www.dartlang.org قابل دسترسی میباشد. این کتابخانه، دارای انعطاف پذیری فوق العاده بالایی است و کد نویسی Java Script را راحتتر میکند. در حال حاضر هیچ مرورگری به غیر از Chromium از این تکنولوژی پشتیبانی نمیکند و جهت تسهیل در کدنویسی، باید از ویرایشگر Dart Editor استفاده کنید. این ویرایشگر کدهای نوشته شده را به دو صورت Native و JavaScript Compiled در اختیار مرورگر قرار میدهد. در ادامه با نحوهی کار و راه اندازی Dart آشنا خواهید شد.
ابتدا Dart و ویرایشگر مربوط به آن را توسط لینکهای زیر دانلود کنید:
دانلود نسخه 64 بیتی دارت + ویرایشگر
دانلود نسخه 32 بیتی دارت + ویرایشگر
بعد از اینکه فایلهای فوق را از حالت فشرده خارج کردید، پوشه ای با نام dart ایجاد مینماید. وارد پوشه dart شده و DartEditor را اجرا کنید.
توجه: جهت اجرای dart به JDK 6.0 یا بالاتر نیاز دارید
در مرحله بعد نمونه کدهای Dart را از لینک زیر دانلود نمایید و از حالت فشرده خارج کنید. پوشه ای با نام one-hour-codelab ایجاد میگردد.
از منوی File > Open Existing Folder… پوشه one-hour-codelab را باز کنید .
توضیحات
- پوشه packages و همچنین فایلهای pubspec.yaml و pubspec.lock شامل پیش نیازها و Package هایی هستند که جهت اجرای برنامههای تحت Dart مورد نیاز هستند. Dart Editor این نیازمندیها را به صورت خودکار نصب و تنظیم میکند.
توجه: اگر پوشه Packages را مشاهده نکردید و یا در سمت چپ فایلها علامت X قرمز رنگ وجود داشت، بدین معنی است که package ها به درستی نصب نشده اند. برای این منظور بر روی pubspec.yaml کلیک راست نموده و گزینه Get Pub را انتخاب کنید. توجه داشته باید که بدلیل تحریم ایران توسط گوگل باید از ابزارهای عبور از تحریم استفاده کنید.
- 6 پوشه را نیز در تصویر فوق مشاهده میکنید که نمونه کد piratebadge را بصورت مرحله به مرحله انجام داده و به پایان میرساند.
- Dart SDK شامل سورس کد مربوط به تمامی توابع، متغیرها و کلاس هایی است که توسط کیت توسعه نرم افزاری Dart ارائه شده است.
- Installed Packages شامل سورس کد مربوط به تمامی توابع، متغیرها و کلاسهای کتابخانههای اضافهتری است که Application به آنها وابسته است.
گام اول: اجرای یک برنامه کوچک
در این مرحله سورس کدهای آماده را مشاهده میکنید و با ساختار کدهای Dart و HTML آشنا میشوید و برنامه کوچکی را اجرا مینمایید.
در Dart Editor پوشه 1-blankbadge را باز کنید و فایلهای piratebadge.html و piratebadge.dart را مشاهده نمایید.
کد موجود در فایل piratebadge.html
<html> <head> <meta charset="utf-8"> <title>Pirate badge</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="piratebadge.css"> </head> <body> <h1>Pirate badge</h1> <div> TO DO: Put the UI widgets here. </div> <div> <div> Arrr! Me name is </div> <div> <span id="badgeName"> </span> </div> </div> <script type="application/dart" src="piratebadge.dart"></script> <script src="packages/browser/dart.js"></script> </body> </html>
توضیحات
- در کد HTML ، اولین تگ <script> ، فایل piratebadge.dart را جهت پیاده سازی دستورات dart به صفحه ضمیمه مینماید
- Dart Virtual Machine (Dart VM) کدهای Dart را بصورت Native یا بومی ماشین اجرا میکند. Dart VM کدهای خود را در Dartium که یک ویرایش ویژه از مرورگر Chromium میباشد اجرا میکند که میتواند برنامههای تحت Dart را بصورت Native اجرا کند.
- فایل packages/browser/dart.js پشتیبانی مرورگر از کد Native دارت را بررسی میکند و در صورت پشتیبانی، Dart VM را راه اندازی میکند و در غیر این صورت JavaScript کامپایل شده را بارگزاری مینماید.
کد موجود در piratebadge.dart
void main() { // Your app starts here. }
- این فایل شامل تابع main میباشد که تنها نقطه ورود به application است. تگ <script> موجود در piratebadge.html برنامه را با فراخوانی این تابع راه اندازی میکند.
- تابع main() یک تابع سطح بالا یا top-level میباشد.
- متغیرها و توابع top-level عناصری هستند که خارج از ساختار تعریف کلاس ایجاد میشوند.
جهت اجرای برنامه در Dart Editor بر روی piratebadge.html کلیک راست نمایید و گزینه Run in Dartium را اجرا کنید. این فایل توسط Dartium اجرا میشود و تابع main() را فراخوانی میکند و صفحه ای همانند شکل زیر را نمایش میدهد.
گام دوم: افزودن فیلد input
توجه داشته باشید که در این مرحله یا میتوانید تغییرات مورد نظر خود را در طی آموزش بر روی پوشهی 1-blankbadge اعمال کنید و یا به پوشههای تهیه شده در نمونه کد موجود در همین پروژه مراجعه نمایید.
در این مرحله یک تگ <input> به تگ <div class=”widgets”> اضافه کنید.
... <div> <div> <input type="text" id="inputName" maxlength="15"> </div> </div> ...
سپس کتابخانه dart:html را به ابتدای فایل piratebadge.dart اضافه کنید.
import 'dart:html';
توضیحات
- دستور فوق کلاسها و Resource های موجود در کتابخانه dart:html را اضافه میکند.
- از حجیم شدن کدهای خود نگران نباشید، زیرا فرایند کامپایل کدهای اضافی را حذف خواهد کرد.
- کتابخانه dart:html شامل کلاسهایی جهت کار با عناصر DOM و توابعی جهت دسترسی به این عناصر میباشد.
- در مباحث بعدی یاد میگیرید که با استفاده از کلمه کلیدی show فقط کلاسهایی را import کنید که به آن نیاز دارید.
- اگر کتابخانه ای در هیچ بخش کد استفاده نشود، خود Dart Editor به صورت warning اخطار میدهد و میتوانید آن را حذف کنید.
دستور زیر را در تابع main بنویسید تا رویداد مربوط به ورود اطلاعات در فیلد input را مدیریت نمایید.
void main() { querySelector('#inputName').onInput.listen(updateBadge); }
توضیحات
- تابع querySelector() در کتابخانه dart:html تعریف شده است و یک المنت DOM را جستجو مینماید. پارامتر ورودی آن یک selector میباشد که در اینجا فیلد input را توسط #inputName جستجو نمودیم که یک ID Selector میباشد.
- نوع خروجی این متد یک شی از نوع DOM میباشد.
- تابع onInput.Listen() رویدادی را برای پاسخگویی به ورود اطلاعات در فیلد input تعریف میکند. زمانی که کاربر اطلاعاتی را وارد نماید، تابع updateBadge فراخوانی میگردد.
- رویداد input زمانی رخ میدهد که کاربر کلیدی را از صفحه کلید فشار دهد.
- رشتهها همانند جاوا اسکریپت میتوانند در " یا ' قرار بگیرند.
تابع زیر را به صورت top-level یعنی خارج از تابع main تعریف کنید.
... void updateBadge(Event e) { querySelector('#badgeName').text = e.target.value; }
توضیحات
- این تابع محتوای المنت badgeName را به محتوای وارد شده در فیلد input تغییر میدهد.
- پارامتر ورودی این تابع شی e از نوع Event میباشد و به همین دلیل میتوانیم این تابع را یک Event Handler بنامیم.
- e.target به شی ای اشاره میکند که موجب رخداد رویداد شده است و در اینجا همان فیلد input میباشد
- با نوشتن کد فوق یک warning را مشاهده میکنید که بیان میکند ممکن است خصوصیت value برای e.target وجود نداشته باشد. برای حل این مسئله کد را بصورت زیر تغییر دهید.
... void updateBadge(Event e) { querySelector('#badgeName').text = (e.target as InputElement).value; }
توضیحات
- کلمه کلیدی as به منظور تبدیل نوع استفاده میشود که e.target را به یک InputElement تبدیل میکند.
همانند گام اول برنامه را اجرا کنید و نتیجه را مشاهده نمایید. با تایپ کردن در فیلد input به صورت همزمان در کادر قرمز رنگ نیز نتیجه تایپ را مشاهده مینمایید.
using System;
using System.Diagnostics;
using Microsoft.Office.Tools.Word;
using Action = Microsoft.Office.Tools.Word.Action;
private SmartTag _st;
private void init()
{
try
{
//Enable Smart Tags in Word
if (!Application.Options.LabelSmartTags)
{
//ممکن است اسمارت تگها در ورد غیرفعال باشند. به این صورت میشود آنها را فعال کرد
Application.Options.LabelSmartTags = true;
}
_st = new SmartTag(@"www.microsoft.com/Demo#FarsiSmartTag", @"فارسی به پارسی");
//دریافت واژههای فارسی از دیتابیس و افزودن خودکار آنها به اسمارت تگها
if (!DBhelper.AddSmartTagItems(_st, "select distinct farsi from tblFarsiToParsi")) return;
Action stActions = new Action("تبدیل");//تعریف یک اکشن جدید
stActions.Click += stActions_Click;//انتساب روالهای رخداد گردان
stActions.BeforeCaptionShow += stActions_BeforeCaptionShow;
_st.Actions = new[] { stActions };
VstoSmartTags.Add(_st);//افزودن اسمارت تگ به مجموعه
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}
private void ThisAddIn_Startup(object sender, EventArgs e)
{
init();
}
static void stActions_BeforeCaptionShow(object sender, ActionEventArgs e)
{
try
{
Action clickedAction = sender as Action;
if (clickedAction != null)
{
string parsi = DBhelper.FindParsi(e.Text);//معادل پارسی از دیتابیس دریافت میشود
clickedAction.Caption = (parsi == string.Empty ? e.Text : parsi);
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}
static void stActions_Click(object sender, ActionEventArgs e)
{
try
{
Action clickedAction = sender as Action;
if (clickedAction != null)
{
e.Range.Text = clickedAction.Caption;//جایگزینی متن موجود با عنوانی که پیشتر پارسی شده است
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}
using System;
using System.Data.SQLite;
using System.Diagnostics;
using System.Reflection;
using Microsoft.Office.Tools.Word;
namespace Farsi2Parsi
{
class DBhelper
{
#region Methods (2)
// Public Methods (2)
public static bool AddSmartTagItems(SmartTag st, string strSQL)
{
SQLiteDataReader myReader = null;
SQLiteCommand sqlCmd = null;
bool ret = false;
try
{
SQLiteConnection sqlCon = new SQLiteConnection
{
ConnectionString = "Data Source=" + ConStr.ConnectionString
};
sqlCon.Open();
sqlCmd = new SQLiteCommand(strSQL, sqlCon);
myReader = sqlCmd.ExecuteReader();
if (myReader != null)
while (myReader.Read())
{
if (myReader.GetValue(0) != DBNull.Value)
st.Terms.Add(myReader.GetValue(0).ToString());
}
ret = true;
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex + "\n" + Environment.CurrentDirectory + "\n" +
Assembly.GetExecutingAssembly().Location, EventLogEntryType.Error, 7);
}
finally
{
if (myReader != null)
myReader.Close();
if (sqlCmd != null)
sqlCmd.Connection.Close();
}
return ret;
}
public static string FindParsi(string farsi)
{
SQLiteDataReader myReader = null;
SQLiteCommand sqlCmd = null;
string ret = string.Empty;
string strSQL = "select parsi from tblFarsiToParsi where farsi='" + farsi.Replace("'", "''") + "'";
try
{
SQLiteConnection sqlCon = new SQLiteConnection
{
ConnectionString = "Data Source=" + ConStr.ConnectionString
};
sqlCon.Open();
sqlCmd = new SQLiteCommand(strSQL, sqlCon);
myReader = sqlCmd.ExecuteReader();
if (myReader != null)
{
myReader.Read(); //اولین مورد کافی است
if (myReader.GetValue(0) != DBNull.Value)
ret = myReader.GetValue(0).ToString();
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex + "\n" + Environment.CurrentDirectory + "\n" +
Assembly.GetExecutingAssembly().Location, EventLogEntryType.Error, 8);
}
finally
{
if (myReader != null)
myReader.Close();
if (sqlCmd != null)
sqlCmd.Connection.Close();
}
return ret;
}
#endregion Methods
}
}
class ConStr
{
public static string ConnectionString
{
get
{
return Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\FarsiToParsi").GetValue("folder") + "\\ErrorsBank.sqlite";
}
}
}
using Microsoft.ML.Data; namespace CreditCardFraudDetection.DataModels { public class ModelInput { [ColumnName("Time"), LoadColumn(0)] public float Time { get; set; } [ColumnName("V1"), LoadColumn(1)] public float V1 { get; set; } [ColumnName("V2"), LoadColumn(2)] public float V2 { get; set; } [ColumnName("V3"), LoadColumn(3)] public float V3 { get; set; } [ColumnName("V4"), LoadColumn(4)] public float V4 { get; set; } [ColumnName("V5"), LoadColumn(5)] public float V5 { get; set; } [ColumnName("V6"), LoadColumn(6)] public float V6 { get; set; } [ColumnName("V7"), LoadColumn(7)] public float V7 { get; set; } [ColumnName("V8"), LoadColumn(8)] public float V8 { get; set; } [ColumnName("V9"), LoadColumn(9)] public float V9 { get; set; } [ColumnName("V10"), LoadColumn(10)] public float V10 { get; set; } [ColumnName("V11"), LoadColumn(11)] public float V11 { get; set; } [ColumnName("V12"), LoadColumn(12)] public float V12 { get; set; } [ColumnName("V13"), LoadColumn(13)] public float V13 { get; set; } [ColumnName("V14"), LoadColumn(14)] public float V14 { get; set; } [ColumnName("V15"), LoadColumn(15)] public float V15 { get; set; } [ColumnName("V16"), LoadColumn(16)] public float V16 { get; set; } [ColumnName("V17"), LoadColumn(17)] public float V17 { get; set; } [ColumnName("V18"), LoadColumn(18)] public float V18 { get; set; } [ColumnName("V19"), LoadColumn(19)] public float V19 { get; set; } [ColumnName("V20"), LoadColumn(20)] public float V20 { get; set; } [ColumnName("V21"), LoadColumn(21)] public float V21 { get; set; } [ColumnName("V22"), LoadColumn(22)] public float V22 { get; set; } [ColumnName("V23"), LoadColumn(23)] public float V23 { get; set; } [ColumnName("V24"), LoadColumn(24)] public float V24 { get; set; } [ColumnName("V25"), LoadColumn(25)] public float V25 { get; set; } [ColumnName("V26"), LoadColumn(26)] public float V26 { get; set; } [ColumnName("V27"), LoadColumn(27)] public float V27 { get; set; } [ColumnName("V28"), LoadColumn(28)] public float V28 { get; set; } [ColumnName("Amount"), LoadColumn(29)] public float Amount { get; set; } [ColumnName("Class"), LoadColumn(30)] public bool Class { get; set; } } }
using Microsoft.ML.Data; namespace CreditCardFraudDetection.DataModels { public class ModelOutput { [ColumnName("PredictedLabel")] public bool Prediction { get; set; } public float Score { get; set; } } }
IDataView trainingDataView = mlContext.Data.LoadFromTextFile<ModelInput>( path: dataFilePath, hasHeader: true, separatorChar: ',', allowQuoting: true, allowSparse: false);
var dataProcessPipeline = mlContext.Transforms.Concatenate("Features", new[] { "Time", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", "V24", "V25", "V26", "V27", "V28", "Amount" });
// Choosing algorithm var trainer = mlContext.BinaryClassification.Trainers.LightGbm(labelColumnName: "Class", featureColumnName: "Features"); // Appending algorithm to pipeline var trainingPipeline = dataProcessPipeline.Append(trainer);
ITransformer model = trainingPipeline.Fit(trainingDataView);mlContext.Model.Save(model , trainingDataView.Schema, <path>);
var crossValidationResults = mlContext.BinaryClassification.CrossValidateNonCalibrated(trainingDataView, trainingPipeline, numberOfFolds: 5, labelColumnName: "Class");
var predEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel); ModelInput sampleData = new ModelInput() { time = 0, V1 = -1.3598071336738, ... }; ModelOutput predictionResult = predEngine.Predict(sampleData); Console.WriteLine($"Actual value: {sampleData.Class} | Predicted value: {predictionResult.Prediction}");
private ITransformer SetupMlnetModel(string tensorFlowModelFilePath) { var pipeline = _mlContext.<preprocess-data> .Append(_mlContext.Model.LoadTensorFlowModel(tensorFlowModelFilePath) .ScoreTensorFlowModel( outputColumnNames: new[]{TensorFlowModelSettings.outputTensorName }, inputColumnNames: new[] { TensorFlowModelSettings.inputTensorName }, addBatchDimensionInput: false)); ITransformer mlModel = pipeline.Fit(CreateEmptyDataView()); return mlModel; }
[PageAuthorization(AuthorizationType.ApplyRequiredRoles, "IsAdmin, CanAddNewUser")]
/// <summary> /// وضعیت اعتبار سنجی صفحه را مشخص میکند /// </summary> public enum AuthorizationType { /// <summary> /// همه میتوانند بدون اعتبار سنجی، دسترسی به این صفحات داشته باشند /// </summary> AllowAnonymous, /// <summary> /// کاربران وارد شده به سیستم بدون محدودیت به این صفحات دسترسی خواهند داشت /// </summary> FreeForAuthenticatedUsers, /// <summary> /// بر اساس نام نقشهایی که مشخص میشوند تصمیم گیری خواهد شد /// </summary> ApplyRequiredRoles }
[ImplementPropertyChanged] // AOP public class LoginPageModel : DataErrorInfoBase
System.IO.FileNotFoundException
System.IO.FileLoadExceptio
<?xml version="1.0"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemasmicrosoftcom:asm.v1"> <probing privatePath="AuxFiles;bin\subdir" /> <dependentAssembly> <assemblyIdentity name="SomeClassLibrary" publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" /> <codeBase version="2.0.0.0" href="http://www.Wintellect.com/SomeClassLibrary.dll" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="TypeLib" publicKeyToken="1f2e74e897abbcfe" culture="neutral"/> <bindingRedirect oldVersion="3.0.0.03.5.0.0" newVersion="4.0.0.0" /> <publisherPolicy apply="no" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
Probing | در
قسمت بیستم گفتیم که در این المان، مکانهایی را که CLR برای پیدا کردن
اسمبلیهای با نام ضعیف، باید اسکن کند، وارد میکنیم که هر مسیر با , از هم جدا شدهاست. برای اسمبلیهای با نام قوی CLR باید داخل GAC را نگاه
کند و در URL هایی که از طریق المان CodeBase مشخص کردهایم. اگر المان
CodeBase مشخص نشود، CLR برای پیدا کردن اسمبلیهای با نام قوی، داخل
دایرکتوریهای این المان را اسکن خواهد کرد. |
Dependent Assembly اول | در
اولین فرزند این المان، Assembly Identity یک اسمبلی با مشخصاتی مثل
Culture و توکن عمومی معرفی میشود و در BindingRedirect به CLR اطلاع
میدهد موقعی که به دنبال نسخه یک این اسمبلی است، نسخهی دو آن را برای
استفاده جایگزین کند. |
Code Base | این
المان میگوید که وقتی CLR سعی در پیدا کردن نسخهی 2 اسمبلی را دارد، آن را
از طریق آدرس مورد نظر پیدا کند. این المان میتواند برای اسمبلیهای با نام
ضعیف هم کار کند. |
Dependent Assembly دوم | این مورد هم همانند سابق است با این تفاوت که گسترهی نسخه 3 تا 3.5 را به نسخهی 4 تغییر میدهد. |
Publisher Policy | اگر
سازمان تولید کننده این اسمبلی فایلی برای تعیین Policy به همراه اسمبلی
ارائه کرده باشد، این المان باعث میشود این فایل ندیده گرفته شود (در مورد
فایل Policy در آینده صحبت میکنیم). |
نکته : اگر مدیر بخواهد تمام برنامههای موجود از این اسمبلی جدید استفاده کنند باید فایل machine.config را ویرایش کند.
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>