Activator.CreateInstance: Could not load type from

2019-06-17 01:59发布

问题:

I'm trying to create an instance of a class implemented in a plugin .dll in my project to do type discovery. I'm receiving this exception:

Could not load type 'Action' from assembly 'SquidReports.DataCollector.Plugin.BES, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

This is the exact method signature I'm using: https://msdn.microsoft.com/en-us/library/d133hta4(v=vs.110).aspx

In other words, I'm attempting to spawn the object based on the Assembly name and the class name, like so:

object modelObject = Activator.CreateInstance((string)modelInfo.AssemblyName, (string)modelInfo.ModelName);

An important part to note here is that I'm using the 'Short' name of the assembly as opposed to the 'full' name (including Version, Culture and PublicToken). However, MSDN clearly states:

'assemblyName' can be either of the following: The simple name of an assembly, without its path or file extension.

  • For example, you would specify TypeExtensions for an assembly whose path and name are .\bin\TypeExtensions.dll.

  • The full name of a signed assembly, which consists of its simple name, version, culture, and public key token; for example, "TypeExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=181869f2f7435b51".

Specifically, I'm trying to create an instance of class 'Action' defined in the Assembly 'SquidReports.DataCollector.Plugin.BES'. I'm explicitly referencing this assembly as a using directive at the top of the exact same *.cs file where I'm trying to create the instance.

I've tried the following suggestions from previous questions/answers:

Clean out your solution, rebuild and try again This seems to work in some ASP.NET projects, but this is plain old console app.

Check the referenced assemblies in your config file Again, this is a simple console app that only uses the GAC and libraries in the different projects of the same solution

1. Make sure the assembly is in the correct working directory:

Here we are...

2. Make sure the assembly is the same version on-disk

Yup...

3. The final recommendation was to use fuslogvw.exe.

I Have no experience using the tool, but there is one thing that I did find odd. Upon running the debug session, both a long-named and short-named version of my assembly showed up:

I had a look at both logs.

The short-named version does seem to generate some warnings:

=== Pre-bind state information ===

LOG: DisplayName = SquidReports.DataCollector.Plugin.BES Partial) WRN: Partial binding information was supplied for an assembly:

WRN: Assembly Name: SquidReports.DataCollector.Plugin.BES | Domain ID: 1

WRN: A partial bind occurs when only part of the assembly display name is provided.

WRN: This might result in the binder loading an incorrect assembly.

WRN: It is recommended to provide a fully specified textual identity for the assembly,

WRN: that consists of the simple name, version, culture, and public key token.

WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.

... but it ends with being loaded successfully, and it clearly mentions my assembly at the correct location:

LOG: Attempting download of new URL file:///C:/Source/C#/SquidReports/SquidReports.DataCollector/bin/x86/Debug/SquidReports.DataCollector.Plugin.BES.DLL.

The log for the long-named version contains no suspicious messages.

Any more ideas?

EDIT: Here is a minimal definition of the Action class. It's purely a model-class.

public class Action : ICollectible
{
    public Action()
    {
        // Empty constructor
    }

    public Action(int actionID, string siteID, string name)
    {
        this.ActionID = actionID;
        this.SiteID = siteID;
        this.Name = name;
    }

    public int ID           { get; set; }   // Identity ID assigned by DB
    [Key]
    public int ActionID     { get; set; }   // Identity ID assigned by API
    public string SiteID    { get; set; }
    public string Name      { get; set; }
}

ICollectible interface and [Key] attribute are part of yet another assembly. Not sure if that would have effect?

EDIT 2: As Erik points out below, obviously I have done the exact same checks on this OTHER assembly as well.

回答1:

As you have found out, the assembly is being loaded, it just can't find the type (Action). You have to specify the full name of the type, Namespace.Action for .NET to find it.