سؤال

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

تحرير / إجابتي:

واو ، استغرق الأمر لحظة للعودة إلى هذا واحد. لسوء الحظ ، تركت شيئًا مهمًا من السؤال الأصلي.

جزء مهم: أنا أستخدم مكتبة Rhinodsl Ayende كما يوصي في الكتاب. لديّ إمكانية الوصول إلى برنامج التحويل البرمجي في فئتي الفرعية من dslengine والذي يبدو هكذا:

public class JobEngine : DslEngine
{
    protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls)
    {
        pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz"));
    }
}

لتغيير أقل والحصول على ما أردت ، أحتاج إلى إضافة سطر واحد ...

public class JobEngine : DslEngine
{
    protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls)
    {
        compiler.Parameters.GenerateInMemory = false; // <--- This one.
        pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz"));
    }
}

تسبب هذا في إخراج المترجم التجميع إلى دليل ~ adollocalsettings temp ومن ثم يمكنني عكسه. من المهم أن نلاحظ أن إجراء هذا التغيير تسبب في كسر بقية البرنامج (لم يعد بإمكان Rhinodsl العثور على التجميعات في الذاكرة لأنني أخرجها إلى القرص) ، لذلك يعد هذا مفيدًا فقط كأداة تصحيح الأخطاء.

هل كانت مفيدة؟

المحلول

ابحث عن مكان إنشاء إنشاء خط أنابيب ، قم بتغيير خط الأنابيب من التجميع إلى التجميع

نصائح أخرى

نعم AssemblyBuilder الفصل لديه Save طريقة لهذا الغرض. تحتاج إلى استخدام الوضع المناسب لهذا ، وهو على الأرجح RunAndSave:

AssemblyBuilder builder =
    AppDomain.CurrentDomain.DefineDynamicAssembly(
        name, AssemblyBuilderAccess.RunAndSave);
// build assembly
builder.Save(path);

إذا كنت تستطيع الحصول على التجميع في وقت التشغيل.

بمعنى آخر

Assembly assembly = typeof(YourDynamicType).Assembly;

يمكنك بعد ذلك إلقاء هذا التجميع في AssemblyBuilder والاتصال بالطريقة حفظ.

AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly;
assemblyBuilder.Save(yourPath);

قد تكون هناك طريقة أسهل للقيام بذلك ، ولكن إذا كنت لا تمانع في استخدام WindBG ، فيمكنك حفظ أي مجموعة مُدارة محملة من الذاكرة (تستخدم Windbg وحدة المصطلح ، ولكنها تعمل أيضًا مع التجميعات المدارة أيضًا).

استخدم ال !savemodule أمر مع عنوان التجميع. إذا لم يكن لديك العنوان ، فاستخدم lm vm أمر مع اسم الوحدة النمطية. بعد ذلك تحصل على مجموعة DLL منتظمة ، يمكنك فحصها في العاكس.

بالطبع قد تنظر أيضًا إلى رمز IL في الذاكرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top