كيف تحصل على مساحة اسم الجذر الخاصة بالتجميع؟

إعطاء مثال System.Reflection.Assembly .

0
وأضاف تحرير
الآراء: 1

13 إجابة

غير ممكن. لا شيء يحدد مساحة اسم "الجذر". مساحة الاسم الافتراضية في الخيارات هي شيء استوديو مرئي ، وليس شيء .net

0
وأضاف
@ Roboblob رد دارين صحيح تقنيا. المنجم هو مجرد فائدة في 95 ٪ أو نحو ذلك من الحالات حيث تريد معرفة ذلك في سياق بناء مشروع في VS.
وأضاف المؤلف Lisa, مصدر
أدناه نشر من المستخدم ليزا يعمل في الواقع حتى يتم وضع علامة على هذه الإجابة كإجابة ولكن دون سبب وجيه.
وأضاف المؤلف Roboblob, مصدر

قد يكون هناك أي عدد من مساحات الأسماء في تجميع معين ، ولا يتطلب أي شيء منهم بدء من جذر مشترك. أفضل ما يمكن أن تفعله هو أن تعكس جميع الأنواع في تجميع وإنشاء قائمة من مساحات الأسماء الفريدة الموجودة فيه.

0
وأضاف

هناك بالفعل طريقة غير مباشرة للحصول عليه ، عن طريق تعداد أسماء موارد البيان التجميعية. الاسم الذي تريده ينتهي بجزء منه الذي تعرفه.

Rather than repeat the code here, please see get Default namespace name for Assembly.GetManifestResourceStream() method

0
وأضاف

كان السؤال الذي تلقيته هنا هو: "إذا اتصلت بأساليب المكتبة رمز N ، وكنت أريد مساحة اسم المشروع - على سبيل المثال تطبيق MVC الذي يعمل بالفعل - كيف يمكنني الحصول عليه؟"

القليل من المتسللين ولكن يمكنك فقط الحصول على التكدس والتصفية:

    public static string GetRootNamespace()
    {
        StackTrace stackTrace = new StackTrace();
        StackFrame[] stackFrames = stackTrace.GetFrames();
        string ns = null;
        foreach(var frame in stackFrames)
        {
            string _ns = frame.GetMethod().DeclaringType.Namespace;
            int indexPeriod = _ns.IndexOf('.');
            string rootNs = _ns;
            if (indexPeriod > 0)
                rootNs = _ns.Substring(0, indexPeriod);

            if (rootNs == "System")
                break;
            ns = _ns;
        }

        return ns;
    }

كل هذا يفعله هو الحصول على stacktrace ، تشغيل الأساليب من أحدث دعا إلى الجذر ، وتصفية للنظام. بمجرد أن يعثر على استدعاء نظام فإنه يعرف أنه ذهب بعيدًا ، ويعيد لك مساحة الاسم مباشرة فوقه. سواء كنت تقوم بتشغيل وحدة اختبار ، أو تطبيق MVC ، أو خدمة ، فستكون حاوية النظام أعمق مستوى 1 من مساحة اسم الجذر للمشروع الخاص بك ، لذا فويلا.

في بعض السيناريوهات حيث يكون رمز النظام وسيطًا (مثل System.Task) على طول التتبع ، سيؤدي هذا إلى عرض إجابة خاطئة. كان هدفي هو أخذ بعض كود بدء التشغيل على سبيل المثال والسماح له بالبحث بسهولة عن فئة أو وحدة تحكم أو أي شيء موجود في مساحة الاسم الجذر ، حتى إذا كانت الشفرة التي تقوم بهذا العمل موجودة في المكتبة. هذا ينجز تلك المهمة.

أنا متأكد من أنه يمكن تحسينه - أنا متأكد من أن هذه الطريقة السخيفة للقيام بالأشياء يمكن تحسينها بطرق عديدة ، والتحسينات موضع ترحيب.

0
وأضاف

مساحات الأسماء ليس لها علاقة بالجمعيات - أي تعيين بين مساحة الاسم والفئات في تجميع يرجع فقط إلى اصطلاح التسمية (أو المصادفة).

0
وأضاف
في حين أوافق ، تجدر الإشارة إلى أن مشروع Visual Studio يحتوي على مساحة اسم افتراضية ، وإذا كنت تستخدم Visual Studio لتضمين مورد ، فسيتم اشتقاق اسم مورد بيان المصدر هذا من مساحة الاسم الافتراضية وسيظهر ليعرفه التجميع نفسه إذا كنت دائمًا باستخدام Visual Studio لإنشاء التجميع. ودعونا نواجه الأمر هذا أمر شائع جدًا.
وأضاف المؤلف Lisa, مصدر

لا تحتوي التجميعات بالضرورة على مساحة اسم الجذر. مساحات الأسماء والتجميعات متعامدة.

ما قد تبحث عنه بدلاً من ذلك ، هو العثور على نوع داخل هذه الجمعية ، ثم معرفة ما هي مساحة الاسم الخاصة به.

يجب أن تكون قادراً على إنجاز هذا باستخدام العضو GetExportedTypes() ثم استخدام الخاصية Namespace من أحد مقابض Type التي تم إرجاعها.

مرة أخرى على الرغم من عدم وجود ضمانات كافة الأنواع في نفس مساحة الاسم (أو حتى في نفس التسلسل الهرمي مساحة الاسم).

0
وأضاف

Get Types gives you a list of Type objects defined in the assembly. That object has a namespace property. Remember that an assembly can have multiple namespaces.

0
وأضاف

لقد صادفت هذه المعضلة وفرة من المرات عندما أريد تحميل مورد من التجميع الحالي من خلال تدفق موارده الظاهرة.

الحقيقة أنه إذا قمت بتضمين ملف كمورد في التجميع الخاص بك باستخدام Visual Studio سيتم اشتقاق اسمه المورد الظاهري من مساحة الاسم الافتراضية للتجميع كما هو موضح في مشروع Visual Studio.

الحل الأفضل الذي أتيت إليه (لتفادي ترميز مساحة الاسم الافتراضية كسلسلة ما في مكان ما) هو ببساطة التأكد من أن كود تحميل الموارد الخاص بك هو دائمًا يحدث من داخل فئة موجودة أيضًا في مساحة الاسم الافتراضية ومن ثم النهج التالي شبه العام يمكن استخدامها.

هذا المثال هو تحميل مخطط مضمن.

XmlSchema mySchema;
string resourceName = "MyEmbeddedSchema.xsd";
string resourcesFolderName = "Serialisation";
string manifestResourceName = string.Format("{0}.{1}.{2}",
    this.GetType().Namespace, resourcesFolderName, resourceName);
using (Stream schemaStream = currentAssembly.GetManifestResourceStream(manifestResourceName))
    mySchema = XmlSchema.Read(schemaStream, errorHandler);

See also: How to get Namespace of an Assembly?

Edit: Also noticed a very detailed answer to the question I'm answering at http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e

Another edit in case people with same question come looking: Excellent idea to solve the resource-loading question here: How get the default namespace of project csproj (VS 2008)

0
وأضاف
لديه مشاكل مع دقة الموارد المضمنة عندما لا تطابق اسم التجميع "مساحة الاسم الجذر" للمشروع. شكرا على المشاركة المفيدة
وأضاف المؤلف Ivaylo Slavov, مصدر
لا يمكنك إنشاء فئة دون مساحة اسم واستخدام typeof (DefaultNamespaceHelper) .Namespace؟
وأضاف المؤلف drake7707, مصدر
هذا الرمز يعمل في الواقع. شكر!
وأضاف المؤلف Roboblob, مصدر
GetType(frm).Namespace

frm is the startup Form

0
وأضاف
ماذا لو كان نموذج بدء التشغيل غير موجود في مساحة الاسم الجذر؟
وأضاف المؤلف Patrick Hofman, مصدر

أنا فقط إنشاء فئة داخلية فارغة تسمى الجذر ووضعها في جذر المشروع (على افتراض أن هذا هو مساحة الاسم الجذر الخاص بك). ثم استخدم هذا في كل مكان أحتاج إلى مساحة الاسم الجذر:

typeof(Root).Namespace;

بالتأكيد انتهى بي الأمر بملف غير مستخدم ، ولكنه نظيف.

0
وأضاف
مفيد عند الحاجة إلى ذلك في نفس التجميع ، ولكن لا ترغب في شفرته.
وأضاف المؤلف CSharper, مصدر

أستخدم typeof (App) .Namespace في تطبيق wpf الخاص بي. فئة التطبيق إلزامية لأي تطبيق wpf وهو موجود في الجذر.

0
وأضاف

إضافة إلى جميع الإجابات الأخرى هنا ، ونأمل من دون تكرار المعلومات ، هنا كيف تمكنت من حل هذه المشكلة باستخدام Linq. وضعي مشابه لإجابة ليزا.

حلّي يأتي مع التحذيرات التالية:

  • أنت تستخدم Visual Studio ولديك مساحة اسم جغرافية محددة لمشروعك ، وهو ما أفترض أنه ما تطلبه نظرًا لأنك تستخدم المصطلح "مساحة الاسم الجذر"
  • أنت لا تقوم بتضمين أنواع التشغيل المتداخل من التجميعات المشار إليها
Dim baseNamespace = String.Join("."c,
    Me.GetType().Assembly.ManifestModule.GetTypes().
        Select(Function(type As Type)
                    Return type.Namespace.Split("."c)
                End Function
        ).
        Aggregate(Function(seed As String(), splitNamespace As String())
                        Return seed.Intersect(splitNamespace).ToArray()
                    End Function
        )
)
0
وأضاف

هنا ، كطريقة بسيطة للحصول على مساحة الاسم الأساسية لمشروع موقع ويب.

''' 
''' Returns the namespace of the currently running website '''
 
Public Function GetWebsiteRootNamespace() As String
    For Each Asm In AppDomain.CurrentDomain.GetAssemblies()
        If Asm Is Nothing OrElse Asm.IsDynamic Then Continue For

        For Each Typ In Asm.GetTypes
            If Typ Is Nothing OrElse Typ.Name Is Nothing Then Continue For
            If Typ.Name = "MyProject" Then Return Typ.Namespace.Split("."c)(0)
        Next
    Next

    Return Nothing
End Function

هذا ببساطة بالتحقق من كافة التجميعات التي تم تحميلها لنوع "MyProject" وإرجاع مساحة الاسم الجذر لهذا النوع. وهذا مفيد للتسجيل عندما يكون لديك العديد من مشاريع الويب في حل واحد يتشارك نظام السجل. أمل أن هذا يساعد شخصاما.

0
وأضاف