TypeLoadException บอกว่า 'ไม่มีการใช้งาน' แต่มันถูกนำไปใช้งาน


270

ฉันมีข้อผิดพลาดที่แปลกมากในเครื่องทดสอบของเรา ข้อผิดพลาดคือ:

System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.

ฉันไม่เข้าใจว่าทำไม SetShortมีอยู่ในDummyItemชั้นเรียนและฉันได้คอมไพล์รุ่นที่มีการเขียนไปยังบันทึกเหตุการณ์อีกครั้งเพื่อให้แน่ใจว่าไม่ใช่ปัญหาการปรับใช้ / การกำหนดเวอร์ชัน สิ่งที่แปลกคือรหัสการโทรไม่ได้เรียกSetShortวิธีการ


15
ฉันชอบที่คุณแบ่งปันประสบการณ์ของคุณกับชุมชนเพื่อช่วยพวกเราทุกคนและยังสนับสนุนให้เราอ่านคำตอบอื่น ๆ ด้วยขอบคุณ น่าเศร้าที่ไม่มีข้อเสนอแนะสำหรับฉัน อยากรู้ไหมว่าอะไรที่ทำให้ฉันทำงานจบลง? เริ่มต้น Visual Studio ใหม่ ทำไมฉันไม่ลองก่อน
Paul McLean

ขอบคุณพอลหลังจากอ่านความคิดเห็นของคุณฉันได้ลองแล้วก่อนอื่น ทำงานเหมือน
เครื่องราง

ขอบคุณพอลช่วยฉันสักสองสามชั่วโมงอย่างต่อเนื่องเกาหัวเหมือนลิง ...
Kien Chu

นอกจากนี้หลังจากอัปเดต VS 2017 15.7 แล้ว VS จะบอกให้คุณรีบูท คุณอาจไม่ได้ทำแบบนั้น (เช่นฉันเพราะฉันลืมการประชุม) ฉันได้รับ craploads ของความผิดพลาดเช่นนี้ ...
โครงสร้าง

เพียงเพิ่ม 2p ของฉัน - ฉันพบปัญหานี้เมื่อเรียกใช้การทดสอบหน่วยใน MsTest คลาสที่อยู่ภายใต้การทดสอบอยู่ในชุดประกอบที่ลงนามแล้ว แอสเซมบลีที่แตกต่างกันของรุ่นนี้เกิดขึ้นใน GAC MsTest ได้รับการชุมนุม GAC แทนที่จะใช้หนึ่งจากโฟลเดอร์ถังขยะและพยายามที่จะทำการทดสอบกับมันซึ่งเห็นได้ชัดว่าไม่ได้ทำงาน วิธีแก้ไขคือการลบชุดประกอบ GAC'd
tom redfern

คำตอบ:


244

หมายเหตุ - หากคำตอบนี้ไม่ได้ช่วยคุณโปรดสละเวลาเพื่อเลื่อนดูคำตอบอื่น ๆ ที่ผู้คนเพิ่มไว้

คำตอบสั้น ๆ

สิ่งนี้อาจเกิดขึ้นได้หากคุณเพิ่มวิธีการไปยังอินเทอร์เฟซในแอสเซมบลีที่หนึ่งและจากนั้นไปยังคลาสที่ใช้งานในแอสเซมบลีอื่น แต่คุณสร้างแอสเซมบลีที่ใช้งานใหม่โดยไม่ต้องอ้างอิงรุ่นใหม่

ในกรณีนี้ DummyItem ใช้อินเทอร์เฟซจากชุดประกอบอื่น กระบวนการ SetShort ถูกเพิ่มไปยังอินเทอร์เฟซและ DummyItem - เมื่อเร็ว ๆ นี้ แต่แอสเซมบลีที่ประกอบด้วย DummyItem ถูกสร้างขึ้นใหม่โดยอ้างอิงถึงรุ่นก่อนหน้าของแอสเซมบลีของอินเทอร์เฟซ ดังนั้นวิธี SetShort จึงมีประสิทธิภาพ แต่ไม่มีเมจิกซอสเชื่อมโยงกับวิธีการที่เทียบเท่าในอินเทอร์เฟซ

คำตอบที่ยาว

หากคุณต้องการลองทำซ้ำสิ่งนี้ลองทำสิ่งต่อไปนี้:

  1. สร้างโปรเจ็กต์ไลบรารีคลาส: InterfaceDef เพิ่มคลาสเดียวและสร้าง:

    public interface IInterface
    {
        string GetString(string key);
        //short GetShort(string key);
    }
    
  2. สร้างโครงการห้องสมุดระดับที่สอง: การใช้งาน (พร้อมโซลูชันแยกต่างหาก) คัดลอก InterfaceDef.dll ลงในไดเรกทอรีโครงการและเพิ่มเป็นการอ้างอิงไฟล์เพิ่มเพียงหนึ่งคลาสและสร้าง:

    public class ImplementingClass : IInterface
    {
        #region IInterface Members
        public string GetString(string key)
        {
            return "hello world";
        }
    
        //public short GetShort(string key)
        //{
        //    return 1;
        //}
        #endregion
    }
    
  3. สร้างโครงการคอนโซลที่สาม: ClientCode คัดลอก dll สองตัวลงในไดเรกทอรีโครงการเพิ่มการอ้างอิงไฟล์และเพิ่มรหัสต่อไปนี้ลงในวิธีการหลัก:

     IInterface test = new ImplementingClass();
     string s = test.GetString("dummykey");
     Console.WriteLine(s);
     Console.ReadKey();
    
  4. เรียกใช้รหัสครั้งเดียวคอนโซลบอกว่า "สวัสดีโลก"

  5. ยกเลิกการใส่รหัสในสองโครงการ dll และสร้างใหม่ - คัดลอก dlls ทั้งสองกลับไปยังโครงการ ClientCode สร้างใหม่และลองเรียกใช้อีกครั้ง TypeLoadException เกิดขึ้นเมื่อพยายามสร้างอินสแตนซ์ของ ImplementingClass


1
คุณอาจต้องเพิ่มว่าแอป Console ควรจะสร้างใหม่ด้วย DLLs ใหม่เป็นการอ้างอิง การคัดลอก DLL จะไม่ทำงานและอาจเกิดจากรุ่นไม่ตรงกัน (เช่นหลังจากที่คุณคอมไพล์แหล่ง DLL รุ่นนั้นจะเปลี่ยนไป) นั่นเป็นความเข้าใจที่ยุติธรรมหรือไม่?
shahkalpesh

@shahkalpesh จุดดี - สำหรับฉัน 'ทำงานอีกครั้ง' โดยนัย F5 ฉันได้อัพเดตคำตอบแล้ว แน่นอนทั้งหมดนี้จะไม่เกิดขึ้นด้วยเครื่องมือการควบคุมแหล่งที่ดี แต่ไม่ได้รับฉันเริ่มต้นในเรื่องที่ ...
Benjol

4
อืมดูเหมือนว่าข้อความแสดงข้อผิดพลาดของ Microsoft มีข้อผิดพลาดอยู่ - มันบอกว่าวิธีการเรียน "DummyItem" ไม่มีการใช้งานซึ่งเป็นเท็จอย่างแท้จริง .... ปัญหาคือวิธีการของอินเตอร์เฟสไม่ ไม่ได้ใช้งานโดย DummyItem
Qwertie

3
ทางออกสุดท้ายที่ดีเกี่ยวกับมัน? Microsoft แนะนำวิธีแก้ปัญหาอะไร?
Kiquenet

12
ทางออกคือการลบไฟล์ bin ด้วยตนเอง การเผยแพร่ไม่ได้ดูพวกเขาเป็นการเปลี่ยนแปลงดังนั้นคุณต้องบังคับให้มีการล่าสุด สิ่งนี้ควรถูกบันทึกไว้ในคำตอบที่ได้รับความนิยมสูงสุด
ดีเจ

33

นอกจากคำตอบของผู้ถามที่ได้ระบุไปแล้วอาจมีค่าต่อไปนี้ เหตุผลนี้เกิดขึ้นเนื่องจากเป็นไปได้สำหรับคลาสที่มีวิธีการที่มีลายเซ็นเดียวกันกับวิธีการอินเทอร์เฟซโดยไม่ใช้วิธีนั้น รหัสต่อไปนี้แสดงให้เห็นว่า:

public interface IFoo
{
    void DoFoo();
}

public class Foo : IFoo
{
    public void DoFoo() { Console.WriteLine("This is _not_ the interface method."); }
    void IFoo.DoFoo() { Console.WriteLine("This _is_ the interface method."); }
}

Foo foo = new Foo();
foo.DoFoo();               // This calls the non-interface method
IFoo foo2 = foo;
foo2.DoFoo();              // This calls the interface method

สิ่งนี้แก้ไขได้สำหรับฉันด้วยการเพิ่มระดับของความงงงวยว่าวิธีที่อ้างว่าหายไปนั้นถูกประกาศในอินเทอร์เฟซที่ใช้งานโดยคลาสผู้ปกครองและประกาศอีกครั้งในคลาสย่อย การลบสิ่งที่ซ้ำกันออกจากคลาสย่อยทำให้ข้อผิดพลาดหายไป
ilikeprogramming

22

ฉันได้สิ่งนี้เมื่อแอปพลิเคชันของฉันไม่มีการอ้างอิงไปยังแอสเซมบลีอื่นที่กำหนดคลาสที่วิธีการในข้อความข้อผิดพลาดที่ใช้ การเรียกใช้ PEVerify ให้ข้อผิดพลาดที่เป็นประโยชน์มากขึ้น: "ระบบไม่พบไฟล์ที่ระบุ"


19

ฉันเจอข้อความเดียวกันและนี่คือสิ่งที่เราพบ: เราใช้ DLLs ของบุคคลที่สามในโครงการของเรา หลังจากรีลีสใหม่ออกไปเราได้เปลี่ยนโปรเจ็กต์ของเราให้ชี้ไปที่ชุดใหม่ของ dll และคอมไพล์ได้สำเร็จ

ข้อยกเว้นเกิดขึ้นเมื่อฉันพยายามติดตั้งหนึ่งในคลาสที่มีการเชื่อมต่อของพวกเขาในระหว่างเวลาทำงาน เราทำให้แน่ใจว่าข้อมูลอ้างอิงอื่น ๆ ทั้งหมดเป็นข้อมูลล่าสุด แต่ก็ยังไม่มีโชค เราต้องการสักครู่เพื่อจุด (ใช้เบราว์เซอร์ Object) ว่าประเภทการส่งคืนของวิธีการในข้อความข้อผิดพลาดเป็นชนิดใหม่ที่สมบูรณ์จากการชุมนุมใหม่ที่ไม่ได้รับการยืนยัน

เราเพิ่มการอ้างอิงไปยังแอสเซมบลีและข้อผิดพลาดหายไป

  • ข้อความแสดงข้อผิดพลาดค่อนข้างทำให้เข้าใจผิด แต่ชี้ไปในทิศทางที่ถูกต้องมากกว่าหรือน้อยกว่า (วิธีการที่เหมาะสมข้อความผิด)
  • ข้อยกเว้นเกิดขึ้นแม้ว่าเราจะไม่ได้ใช้วิธีการที่เป็นปัญหา
  • ซึ่งทำให้ฉันมีคำถาม: ถ้าข้อยกเว้นนี้ถูกโยนในกรณีใด ๆ ทำไมคอมไพเลอร์ไม่รับมัน

17

ฉันได้รับข้อผิดพลาดนี้ในสถานการณ์ต่อไปนี้

  • ทั้งแอสเซมบลี A และ B อ้างอิง System.Web.Mvc เวอร์ชัน 3.0.0.0
  • แอสเซมบลีที่อ้างอิงแอสเซมบลี B และมีคลาสที่ใช้อินเทอร์เฟซจากแอสเซมบลี B ด้วยวิธีการที่ส่งคืนคลาสจาก System.Web.Mvc
  • Assembly A อัพเกรดเป็น System.Web.Mvc เวอร์ชั่น 4.0.0.0
  • ชุดประกอบ C วิ่งรหัสด้านล่าง (FertPin.Classes.Contact มีอยู่ในชุดประกอบ A):

var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));

การแก้ไขสำหรับฉันคือการอัพเกรดการอ้างอิง System.Web.Mvc ในแอสเซมบลี B เป็น 4.0.0.0 ดูเหมือนชัดเจนตอนนี้!

ขอบคุณโปสเตอร์ต้นฉบับ!


ฉันมีสิ่งที่คล้ายกัน แต่วิธีอื่น ๆ รอบกับรุ่น วิธีหนึ่งที่กำหนดเป้าหมาย. NET 2 ส่งคืนชนิดจาก v2 ของ System.Windows.Forms การใช้งานที่ถูกแทนที่ในแอสเซมบลี. NET 4 ที่กำหนดเป้าหมายส่งคืนชนิดเดียวกัน แต่จาก v4 ของ System.Windows.Forms มันรวบรวมได้ดี แต่ ReflectionOnlyLoadFrom ไม่ชอบ
Stephen Hewlett

ฉันมีปัญหาคล้ายกันที่เกิดจากการโหลดประเภทที่กำหนดเป้าหมาย. NET2 ลงในบริบท ReflectionOnly ของแอปพลิเคชั่น. NET4 ฉันแก้ไขปัญหาด้วยการเปลี่ยนเส้นทางการร้องขอแอสเซมบลีทั้งหมดของแอสเซมบลี. NET2 แกนไปยังคู่หู. NET4 ของพวกเขาในเหตุการณ์ AppDomain.ReflectionOnlyAssemblyResolve
Chaquotay

นี่คือปัญหาของฉัน :) ขอบคุณ!
Antoan Elenkov

13

อีกครั้งคุณจะได้รับข้อผิดพลาดนี้คือถ้าคุณมีแอสเซมบลีที่เซ็นชื่อรุ่นที่ไม่ถูกต้อง มันไม่ใช่อาการปกติสำหรับสาเหตุนี้ แต่นี่คือสถานการณ์ที่ฉันได้รับ

  • โครงการ asp.net ประกอบด้วยชุดประกอบ A และชุดประกอบ B, B

  • ชุดประกอบ A ใช้ Activator.CreateInstance เพื่อโหลดชุดประกอบ C (เช่นไม่มีการอ้างอิงถึง C ซึ่งสร้างขึ้นแยกต่างหาก)

  • C ถูกสร้างขึ้นโดยอ้างอิงถึงแอสเซมบลีรุ่นเก่ากว่าที่มีอยู่ในปัจจุบัน

หวังว่าจะช่วยให้ใครบางคน - ฉันใช้เวลานานในการคิดเรื่องนี้


9

ฉันมีข้อผิดพลาดนี้เช่นกันมันเกิดจากการใด ๆ ของ CPU exe อ้างอิงใด ๆ ประกอบซีพียูที่จะอ้างอิงการชุมนุม x86

ข้อยกเว้นบ่นเกี่ยวกับวิธีการในชั้นเรียนใน MyApp.Implementations (CPU ใด ๆ ) ซึ่งได้รับ MyApp.Interfaces (CPU ใด ๆ ) แต่ใน fuslogvw.exe ฉันพบ 'พยายามโหลดโปรแกรมด้วยรูปแบบที่ไม่ถูกต้อง' ข้อยกเว้นจาก MyApp .CommonTypes (x86) ซึ่งทั้งคู่ใช้


6

ฉันกลับมาที่นี่ต่อไป ... คำตอบมากมายที่นี่ทำหน้าที่ได้ดีในการอธิบายว่าปัญหาคืออะไร แต่ไม่ใช่วิธีการแก้ไข

วิธีการนี้คือการลบไฟล์ bin ด้วยตนเองในไดเรกทอรีที่เผยแพร่โครงการของคุณ มันจะล้างข้อมูลอ้างอิงทั้งหมดและบังคับให้โครงการใช้ DLLs ล่าสุด

ฉันไม่แนะนำให้ใช้ฟังก์ชั่นลบเครื่องมือเผยแพร่เพราะนี่จะทำให้ IIS ล้มเหลว


ฉันพบสิ่งนี้เป็นกรณีในโครงการที่ไม่ใช่เว็บด้วย - ฉันสะท้อนให้เห็นถึงการชุมนุมหนึ่งในอื่น (โดยใช้ LoadFile) การทำความสะอาดและการสร้างใหม่ไม่ทำงาน - การลบไฟล์ทั้งหมดจากโฟลเดอร์ช่องเก็บของโครงการทั้งสองทำงาน ขอบคุณสำหรับคำแนะนำ!
d219

ฉันต้องทำการตั้งค่า IIS ใหม่อีกครั้งเนื่องจากโครงการนี้กำลังใช้งาน IIS อยู่ภายในเครื่อง (น่าเสียดาย)
ทิมวิลสัน

6

ฉันยังมีวิธีแก้ปัญหาลึกลับอื่นเพื่อข้อความผิดพลาดนี้ ฉันอัพเกรดกรอบงานเป้าหมายของฉันจาก. Net 4.0 เป็น 4.6 และโครงการทดสอบหน่วยของฉันให้ข้อผิดพลาด "System.TypeLoadException ... ไม่มีการใช้งาน" เมื่อฉันพยายามสร้าง นอกจากนี้ยังให้ข้อความแสดงข้อผิดพลาดที่สองเกี่ยวกับวิธีการที่ไม่ได้นำมาใช้เช่นเดียวกับที่กล่าวว่า "งาน 'BuildShadowTask' ล้มเหลวโดยไม่คาดคิด ไม่มีคำแนะนำใดที่นี่ดูเหมือนจะช่วยได้ดังนั้นฉันจึงค้นหา "BuildShadowTask" และพบโพสต์ใน MSDNซึ่งทำให้ฉันใช้ตัวแก้ไขข้อความเพื่อลบบรรทัดเหล่านี้ออกจากไฟล์ csproj ของโครงการทดสอบหน่วย

<ItemGroup>
  <Shadow Include="Test References\MyProject.accessor" />
</ItemGroup>

หลังจากนั้นข้อผิดพลาดทั้งสองก็หายไปและสร้างโครงการ


นี่คือคำตอบสำหรับฉัน ฉันพบข้อผิดพลาดนี้หลังจากอัปเกรดจาก. NET 4.5 เป็น 4.6
twblamer

6

ฉันพบข้อผิดพลาดนี้ในบริบทที่ฉันใช้ Autofac และการโหลดแอสเซมบลีจำนวนมาก

ในขณะที่ทำการดำเนินการแก้ปัญหา Autofac รันไทม์จะไม่สามารถโหลดหนึ่งในแอสเซมบลี Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementationเกิดข้อผิดพลาดบ่นว่า อาการที่เกิดขึ้นเมื่อทำงานบน Windows Server 2012 R2 VM แต่ไม่ได้เกิดขึ้นใน Windows 10 หรือ Windows Server 2016 VM

ImplementationAssemblyอ้างอิงSystem.Collections.Immutable1.1.37 และมีการใช้งานของอินเตอร์เฟซซึ่งถูกกำหนดไว้ในการแยกIMyInterface<T1,T2> อ้างอิง1.1.36DefinitionAssemblyDefinitionAssemblySystem.Collections.Immutable

วิธีการจากIMyInterface<T1,T2>ที่ถูก "ไม่ได้ดำเนินการ" มีพารามิเตอร์ของชนิดซึ่งถูกกำหนดไว้ในIImmutableDictionary<TKey, TRow>System.Collections.Immutable

สำเนาจริงที่System.Collections.Immutableพบในไดเรกทอรีโปรแกรมเป็นรุ่น 1.1.37 บน Windows Server 2012 R2 VM ของฉัน GAC มีสำเนาของSystem.Collections.Immutable1.1.36 ใน Windows 10 และ Windows Server 2016 GAC มีสำเนาของSystem.Collections.Immutable1.1.37 ข้อผิดพลาดในการโหลดเกิดขึ้นเมื่อ GAC มี DLL รุ่นเก่ากว่าเท่านั้น

ดังนั้นสาเหตุของความล้มเหลวในการโหลดการชุมนุมเป็น mismatching System.Collections.Immutableอ้างอิงถึง คำจำกัดความของอินเทอร์เฟซและการใช้งานมีลายเซ็นวิธีการที่เหมือนกัน แต่จริง ๆ แล้วขึ้นอยู่กับรุ่นต่าง ๆSystem.Collections.Immutableซึ่งหมายความว่ารันไทม์ไม่ได้พิจารณาคลาสการใช้งานให้ตรงกับคำจำกัดความของอินเทอร์เฟซ

การเพิ่มการเปลี่ยนเส้นทางการเชื่อมโยงไปยังไฟล์ config ของแอปพลิเคชันของฉันแก้ไขปัญหา:

<dependentAssembly>
        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.1.37.0" newVersion="1.1.37.0" />
</dependentAssembly>

ฉันขอถามคุณว่าคุณพบมันได้อย่างไร? คุณใช้เทคนิคการดีบักที่ไม่ได้มาตรฐานหรือไม่? ฉันได้รับข้อผิดพลาดเดียวกัน แต่ฉันคิดว่ามันเกิดจาก dll ที่แตกต่างกันเพราะฉันมีการเปลี่ยนเส้นทางที่มีผลผูกพันสำหรับ immutables
t3chb0t

1
อืมมม เมื่อไม่นานมานี้ ผมคิดว่าเบาะแสหลักคือการที่ "unimplemented" วิธีการของพารามิเตอร์System.Collections.Immutableที่ใช้ประเภทจาก ในกรณีของฉันไม่มีพารามิเตอร์ตัวเลือกอื่น ๆ หรือประเภทการส่งคืนในวิธีที่ได้รับผลกระทบ ฉันยังจำได้ว่าใช้ ILSpy เพื่อตรวจสอบข้อมูลเมตาที่อ้างอิงในคอมไพล์ "DefinitionAssembly" และ "ImplementationAssembly" DLLs โดยเฉพาะดูรุ่นของข้อมูลอ้างอิง
Hydrargyrum

1
ขอบคุณมาก! ;-) ฉันติดตั้งส่วนขยาย ILSpy สำหรับ Visual Studio และดูที่สาขาการอ้างอิงมีหนึ่งสำหรับSystem.Net.Httpแพ็คเกจฉันเพิ่มdependentAssemblyองค์ประกอบสำหรับมันและคัดลอกข้อมูลจาก ILSpy และมันใช้งานได้ในขณะนี้ข้อผิดพลาดหายไป!
t3chb0t

ฉันคิดออกว่าอะไรคือแอสเซมบลี GAC ที่ไม่ดีโดยใส่สิ่งนี้ลงในโค้ดและวางเบรกพอยต์หลังจากนั้นเพื่อดูค่าและเห็น System.Net.Http สองรุ่นถูกโหลด: var โหลดAssemblies = จาก a ใน AppDomain.CurrentDomain GetAssemblies () orderby a.FullName เลือก (a.FullName, a);
paulie4

5

ฉันได้สิ่งนี้ด้วยการพึ่งพาโครงการรูป "เพชร":

  • โครงการ A ใช้โครงการ B และโครงการ D
  • โครงการ B ใช้โครงการ D

ฉันคอมไพล์โครงการ A ใหม่ แต่ไม่ใช่ Project B ซึ่งอนุญาตให้ Project B "ฉีด" Project Dll เวอร์ชันเก่า


16
ใช่ฉันชอบที่จะคิดว่าเป็นปัญหาเรโนลต์
Benjol

ฉันคิดว่าฉันมีปัญหานี้รุ่นที่คล้ายกัน แต่เพียงระหว่างสองโครงการ ฉันรวบรวมใหม่ด้วยตนเอง หลังจากนั้นก็ทำงานได้อย่างราบรื่น
Departamento B

5

ฉันพบสิ่งนี้เมื่อฉันเปลี่ยนชื่อโครงการ (และชื่อชุดประกอบ) ซึ่งขึ้นอยู่กับโครงการ ASP.NET ประเภทในโครงการเว็บที่ใช้อินเทอร์เฟซในแอสเซมบลีที่อ้างถึง แม้จะเรียกใช้งาน Clean Solution จากเมนู Build แอสเซมบลีที่มีชื่อก่อนหน้านี้ยังคงอยู่ในbinโฟลเดอร์และเมื่อโครงการเว็บของฉันดำเนินการ

var types = AppDomain.CurrentDomain.
   GetAssemblies().
   ToList().
   SelectMany( s => s.GetTypes() /* exception thrown in this call */ )
;

ข้อยกเว้นข้างต้นถูกโยนโดยบ่นว่าวิธีการอินเทอร์เฟซในประเภทการใช้งานเว็บไม่ได้ดำเนินการจริง การลบชุดประกอบในbinโฟลเดอร์ของโครงการเว็บด้วยตนเองสามารถแก้ไขปัญหาได้


4

ฉันยังได้รับข้อผิดพลาดนี้เมื่อก่อนหน้านี้ฉันได้เปิดใช้งานการครอบคลุมโค้ดระหว่างการทดสอบหน่วยสำหรับชุดประกอบหนึ่ง ด้วยเหตุผลบางอย่าง Visual Studio "บัฟเฟอร์" เวอร์ชันเก่าของ DLL นี้โดยเฉพาะแม้ว่าฉันได้ทำการปรับปรุงเพื่อใช้อินเทอร์เฟซเวอร์ชันใหม่ การปิดใช้งานการครอบคลุมโค้ดได้กำจัดข้อผิดพลาด


4

ข้อผิดพลาดนี้อาจเกิดขึ้นได้หากแอสเซมบลีถูกโหลดโดยใช้ Assembly.LoadFrom (String) และกำลังอ้างอิงแอสเซมบลีที่โหลดแล้วโดยใช้แอสเซมบลี. Load (Byte [])

ตัวอย่างเช่นคุณได้ฝังแอสเซมบลีที่อ้างอิงของแอปพลิเคชันหลักเป็นทรัพยากร แต่แอปของคุณโหลดปลั๊กอินจากโฟลเดอร์เฉพาะ

แทนที่จะใช้ LoadFrom คุณควรใช้ Load รหัสต่อไปนี้จะทำงาน:

private static Assembly LoadAssemblyFromFile( String filePath )
{
    using( Stream stream = File.OpenRead( filePath ) )
    {
        if( !ReferenceEquals( stream, null ) )
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read( assemblyData, 0, assemblyData.Length );
            return Assembly.Load( assemblyData );
        }
    }
    return null;
}

3

คำอธิบายสำหรับปัญหาประเภทนี้ที่เกี่ยวข้องกับการจัดการ C ++

หากคุณพยายามที่จะสตับอินเทอร์เฟซที่กำหนดในแอสเซมบลีที่สร้างขึ้นโดยใช้ C ++ ที่มีการจัดการที่มีลายเซ็นพิเศษคุณจะได้รับข้อยกเว้นเมื่อสตับถูกสร้างขึ้น

นี้เป็นจริงสำหรับเงิน Mocks ใด ๆ System.Reflection.Emitและอาจจะกรอบเยาะเย้ยที่ใช้

public interface class IFoo {
  void F(long bar);
};

public ref class Foo : public IFoo {
public:
  virtual void F(long bar) { ... }
};

นิยามอินเตอร์เฟสได้รับลายเซ็นต่อไปนี้:

void F(System.Int32 modopt(IsLong) bar)

โปรดทราบว่าประเภท C ++ longจะจับคู่กับSystem.Int32(หรือเพียงแค่intใน C #) มันเป็นเรื่องที่ค่อนข้างชัดเจนmodoptว่าเป็นสาเหตุของปัญหาดังกล่าวโดย Ayende Rahien ในเงิน Mocks รายชื่อผู้รับจดหมาย


System::Byteผมมีข้อผิดพลาดนี้เมื่อฉันใช้ประเภทข้อมูล ฉันเปลี่ยนลายเซ็นเพื่อยอมรับunsigned shortและท้องฟ้าก็เป็นสีฟ้าอีกครั้ง
Krishter

3

ฉันเพิ่งอัพเกรดโซลูชันจาก MVC3 เป็น MVC5 และเริ่มได้รับข้อยกเว้นเดียวกันจากโครงการทดสอบหน่วยของฉัน

ตรวจสอบการอ้างอิงทั้งหมดที่กำลังมองหาไฟล์เก่า แต่ในที่สุดฉันก็พบว่าฉันจำเป็นต้องทำ bindingRedirects สำหรับ Mvc ในโครงการทดสอบหน่วยของฉัน

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

3

ในกรณีของฉันมันช่วยในการรีเซ็ต WinForms Toolbox

ฉันได้รับข้อยกเว้นเมื่อเปิด a Formในดีไซเนอร์ อย่างไรก็ตามการรวบรวมและเรียกใช้รหัสเป็นไปได้และรหัสการทำงานตามที่คาดไว้ ข้อยกเว้นเกิดขึ้นในการUserControlใช้งานอินเทอร์เฟซจากหนึ่งในห้องสมุดอ้างอิงของฉัน ข้อผิดพลาดเกิดขึ้นหลังจากห้องสมุดนี้ได้รับการปรับปรุง

นี่UserControlคือรายการในกล่องเครื่องมือ WinForms Visual Studio อาจเก็บข้อมูลอ้างอิงเกี่ยวกับไลบรารีรุ่นเก่าหรือกำลังแคชรุ่นที่ล้าสมัยอยู่ที่ไหนสักแห่ง

นี่คือวิธีที่ฉันกู้คืนจากสถานการณ์นี้:

  1. คลิกขวาที่กล่องเครื่องมือ WinForms และคลิกที่Reset Toolboxในเมนูบริบท (สิ่งนี้จะลบรายการที่กำหนดเองออกจากกล่องเครื่องมือ)
    ในกรณีของฉันรายการกล่องเครื่องมือได้รับการคืนสู่สถานะเริ่มต้น อย่างไรก็ตามลูกศรชี้หายไปในกล่องเครื่องมือ
  2. ปิด Visual Studio
    ในกรณีของฉัน Visual Studio สิ้นสุดลงด้วยข้อยกเว้นการละเมิดและถูกยกเลิก
  3. เริ่ม Visual Studio ใหม่
    ตอนนี้ทุกอย่างทำงานได้อย่างราบรื่น

3

FWIW ฉันได้รับสิ่งนี้เมื่อมีไฟล์กำหนดค่าที่เปลี่ยนเส้นทางไปยังเวอร์ชันที่ไม่มีอยู่ของชุดประกอบที่อ้างอิง บันทึกการผสมผสานของการชนะ!


3

ฉันได้รับข้อผิดพลาดนี้เนื่องจากฉันมีคลาสในชุดประกอบ 'C' ซึ่งอยู่ในเวอร์ชัน 4.5 ของเฟรมเวิร์กใช้อินเทอร์เฟซในชุดประกอบ 'A' ซึ่งอยู่บนเวอร์ชัน 4.5.1 ของกรอบงานและทำหน้าที่เป็นคลาสพื้นฐานเพื่อประกอบ 'B' ซึ่งเป็นเวอร์ชัน 4.5.1 ของเฟรมเวิร์กด้วยเช่นกัน ระบบโยนข้อยกเว้นขณะที่พยายามโหลดชุดประกอบ 'B' นอกจากนี้ฉันได้ติดตั้งแพ็คเกจ nuget ที่กำหนดเป้าหมายเป็น. net 4.5.1 ในทั้งสามชุด ด้วยเหตุผลบางอย่างแม้ว่าการอ้างอิงของนักเก็ตจะไม่แสดงในชุดประกอบ 'B' แต่มันก็สร้างได้สำเร็จ

ปรากฎว่าปัญหาที่แท้จริงคือแอสเซมบลีที่อ้างอิงแพคเกจ nuget รุ่นต่าง ๆ ที่ประกอบด้วยอินเทอร์เฟซและลายเซ็นของอินเทอร์เฟซที่มีการเปลี่ยนแปลงระหว่างรุ่น


3

ในกรณีของฉันฉันได้อ้างถึงก่อนหน้านี้mylibโครงการที่อยู่นอกโฟลเดอร์พี่น้องของธุรกรรมซื้อคืน - v1.0การโทรให้ของที่

|-- myrepo
|    |-- consoleApp
|    |-- submodules
|         |-- mylib (submoduled v2.0)
|-- mylib (stale v1.0)

ต่อมาผมก็ทำมันได้อย่างถูกต้องและใช้มันผ่านคอมไพล์ submodule - v2.0ช่วยให้การเรียกร้องว่า consoleAppอย่างไรก็ตามโครงการหนึ่งไม่ได้รับการอัพเดตอย่างถูกต้อง มันยังคงอ้างอิงv1.0โครงการเก่าที่อยู่นอกโครงการคอมไพล์ของฉัน

พลุกพล่านแม้ว่าจะ*.csprojเป็นชัดถ้อยชัดคำผิดและชี้ไปv1.0ที่ Visual Studio IDE แสดงให้เห็นเส้นทางเป็นที่v2.0โครงการ! F12 เพื่อตรวจสอบส่วนต่อประสานและคลาสไปเป็นv2.0เวอร์ชั่นด้วย

แอสเซมบลีที่อยู่ในโฟลเดอร์ bin โดยคอมไพเลอร์คือv1.0เวอร์ชันดังนั้นจึงปวดหัว

ความจริงที่ว่า IDE กำลังโกหกฉันทำให้ยากเป็นพิเศษในการตระหนักถึงข้อผิดพลาด

การแก้ไข : ลบการอ้างอิงโครงการจากConsoleAppและอ่านใหม่

คำแนะนำทั่วไป:คอมไพล์ชุดข้อมูลทั้งหมดใหม่ตั้งแต่เริ่มต้น (ถ้าเป็นไปได้ไม่สามารถใช้สำหรับแพ็คเกจ nuget แน่นอน) และตรวจสอบการประทับวันที่และเวลาในbin\debugโฟลเดอร์ แอสเซมบลีเก่าใด ๆ ที่เป็นปัญหาของคุณ


3

ฉันประสบปัญหาเดียวกันเกือบ ฉันเกาหัวของฉันในสิ่งที่ทำให้เกิดข้อผิดพลาดนี้ ฉันข้ามการตรวจสอบวิธีการทั้งหมดถูกนำไปใช้

บน Googling ฉันได้รับลิงค์นี้จากคนอื่น ๆ จากความคิดเห็น @Paul McLink สองขั้นตอนนี้แก้ไขปัญหาได้

  1. เริ่ม Visual Studio ใหม่
  2. ทำความสะอาดสร้าง (สร้างใหม่)

และข้อผิดพลาดไป

รีสตาร์ทปลั๊กอิน VS

ขอบคุณ Paul :)

หวังว่าจะช่วยคนที่พบข้อผิดพลาดนี้ :)


2

ฉันเจอปัญหานี้ขณะที่เรียกใช้ unittests แอปพลิเคชันทำงานได้ดีและไม่มีข้อผิดพลาด สาเหตุของปัญหาในกรณีของฉันคือฉันได้ปิดอาคารของโครงการทดสอบ การเปิดใช้งานการสร้างโครงการทดสอบของฉันอีกครั้งแก้ปัญหาได้


2

ฉันเห็นสิ่งนี้ใน Visual Studio Pro 2008 เมื่อสองโครงการสร้างแอสเซมบลีที่มีชื่อเดียวกันหนึ่งคลาส lib SDF.dll และอีกหนึ่งที่อ้างถึง lib กับชื่อแอสเซมบลี sdf.exe เมื่อฉันเปลี่ยนชื่อของชุดประกอบการอ้างอิงข้อยกเว้นหายไป


2

นี่หมายความว่าโครงการดำเนินการล้าสมัยในกรณีของฉัน DLL ที่ประกอบด้วยอินเทอร์เฟซถูกสร้างใหม่ แต่การใช้ dll นั้นเก่า


2

นี่คือข้อผิดพลาดของฉัน

เพิ่มexternวิธีการ แต่การวางของฉันผิดพลาด DllImportAttributeได้วางบนเส้นออกความเห็น

/// <returns>(removed for brevity lol)</returns>[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);

การตรวจสอบให้แน่ใจว่าแอตทริบิวต์นั้นถูกรวมอยู่ในแหล่งที่มาแก้ไขปัญหาแล้ว


2

ฉันได้รับบริการ WCF เนื่องจากมีการเลือกประเภทบิลด์ x86 ซึ่งทำให้ถังขยะอยู่ภายใต้ bin \ x86 แทนที่จะเป็น bin การเลือกซีพียูใด ๆ ทำให้ DLL ที่คอมไพล์แล้วไปที่ตำแหน่งที่ถูกต้อง


1

ผมมีปัญหาเหมือนกัน. ฉันพบว่าชุดประกอบของฉันซึ่งโหลดโดยโปรแกรมหลักมีการอ้างอิงบางอย่างโดยตั้งค่า "คัดลอก Local" เป็นจริง สำเนาของการอ้างอิงในเครื่องเหล่านี้กำลังค้นหาการอ้างอิงอื่น ๆ ในโฟลเดอร์เดียวกันซึ่งไม่มีอยู่เนื่องจาก "Copy Local" ของการอ้างอิงอื่นถูกตั้งค่าเป็นเท็จ หลังจากลบการคัดลอกการอ้างอิงที่ "ตั้งใจ" ข้อผิดพลาดได้หายไปเนื่องจากโปรแกรมหลักถูกตั้งค่าให้ค้นหาตำแหน่งที่ถูกต้องของการอ้างอิง เห็นได้ชัดว่าสำเนาของการอ้างอิงในประเทศนั้นทำให้ลำดับของการโทรเกิดความผิดพลาดเนื่องจากสำเนาในตัวเครื่องเหล่านี้ถูกนำมาใช้แทนต้นฉบับดั้งเดิมที่อยู่ในโปรแกรมหลัก

ข้อความนำกลับบ้านคือข้อผิดพลาดนี้ปรากฏขึ้นเนื่องจากการเชื่อมโยงที่ขาดหายไปเพื่อโหลดการชุมนุมที่จำเป็น


1

ในกรณีของฉันฉันพยายามที่จะใช้TypeBuilderในการสร้างประเภท TypeBuilder.CreateTypeโยนข้อยกเว้นนี้ ในที่สุดฉันก็รู้ว่าฉันจำเป็นต้องเพิ่มMethodAttributes.Virtualแอตทริบิวต์เมื่อเรียกTypeBuilder.DefineMethodใช้วิธีการที่ช่วยให้ใช้อินเทอร์เฟซ นี่เป็นเพราะไม่มีการตั้งค่าสถานะนี้วิธีการไม่ได้ใช้อินเทอร์เฟซ แต่เป็นวิธีการใหม่ที่มีลายเซ็นเดียวกันแทน (แม้ไม่มีการระบุMethodAttributes.NewSlot)


1

ในฐานะภาคผนวก: สิ่งนี้สามารถเกิดขึ้นได้หากคุณอัพเดตแพ็คเกจ nuget ที่ใช้ในการสร้างชุดประกอบ fakes สมมติว่าคุณติดตั้ง V1.0 ของแพ็คเกจ nuget และสร้างชุดประกอบ fakes "fakeLibrary.1.0.0.0.Fakes" ถัดไปคุณอัปเดตแพคเกจ nuget เวอร์ชันใหม่ล่าสุดพูด v1.1 ซึ่งเพิ่มวิธีการใหม่ในอินเทอร์เฟซ ไลบรารี Fakes ยังคงค้นหา v1.0 ของไลบรารีอยู่ เพียงถอดชุดประกอบปลอมออกแล้วสร้างใหม่ หากนั่นคือปัญหานี่อาจจะแก้ไขได้


1

ฉันได้รับข้อผิดพลาดนี้หลังจากอัปเดต windows ล่าสุด ฉันมีคลาสบริการที่ตั้งค่าให้รับช่วงต่อจากอินเตอร์เฟส อินเตอร์เฟสมีลายเซ็นต์ที่ส่งคืน ValueTuple ซึ่งเป็นคุณลักษณะใหม่ที่ค่อนข้างยุติธรรมใน C #

ทั้งหมดที่ฉันเดาได้คือ windows update ติดตั้ง new แต่ถึงแม้จะอ้างอิงอย่างชัดเจนปรับปรุงการเปลี่ยนเส้นทางการผูก ฯลฯ ... ผลลัพธ์สุดท้ายคือการเปลี่ยนลายเซ็นของวิธีการเป็นมาตรฐาน "ฉันเดาว่าคุณสามารถพูดได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.