【问题标题】:Could not find or load assembly "tmpAssembly,无法找到或加载程序集“tmpAssembly,
【发布时间】:2016-01-21 16:57:11
【问题描述】:

我正在尝试使用动态生成的类型作为名为 codeeffects (www.codeeffects.com) 的业务规则编辑器的来源,但是我遇到了这个异常

Could not find or load assembly "tmpAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null". Error message: Could not load file or assembly 'tmpAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. (Error S103)

控制器中的索引动作是:

[HttpGet]
        public ActionResult Index()
        {
            IMyInterface myObject = (IMyInterface)ObjectBuilder.CreateOurNewObject();
            Type t = myObject.GetType();
            ViewBag.Rule = RuleModel.Create(t);
            return View();
        }

而创建新对象的方法是。

public static object CreateOurNewObject()
        {
            string _xml = "<root>" +
                "<column name=\"Name\">Miron</column>" +
                "<column name=\"LastName\">Abramson</column>" +
                "<column name=\"Blog\">www.blog.mironabramson.com</column>" +
                "</root>";

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(_xml);

            // create a dynamic assembly and module 
            AssemblyName assemblyName = new AssemblyName();
            assemblyName.Name = "tmpAssembly";
            System.Reflection.Emit.AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");

            // create a new type builder
            TypeBuilder typeBuilder = module.DefineType("BindableRowCellCollection", TypeAttributes.Public | TypeAttributes.Class);

            typeBuilder.AddInterfaceImplementation(typeof(IMyInterface));

            // Loop over the attributes that will be used as the properties names in out new type
            foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
            {
                string propertyName = node.Attributes["name"].Value;

                // Generate a private field
                FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
                // Generate a public property
                PropertyBuilder property =
                    typeBuilder.DefineProperty(propertyName,
                                     PropertyAttributes.None,
                                     typeof(string),
                                     new Type[] { typeof(string) });

                // The property set and property get methods require a special set of attributes:

                MethodAttributes GetSetAttr =
                    MethodAttributes.Public |
                    MethodAttributes.HideBySig;

                // Define the "get" accessor method for current private field.
                MethodBuilder currGetPropMthdBldr =
                    typeBuilder.DefineMethod("get_value",
                                               GetSetAttr,
                                               typeof(string),
                                               Type.EmptyTypes);

                // Intermediate Language stuff...
                ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
                currGetIL.Emit(OpCodes.Ldarg_0);
                currGetIL.Emit(OpCodes.Ldfld, field);
                currGetIL.Emit(OpCodes.Ret);

                // Define the "set" accessor method for current private field.
                MethodBuilder currSetPropMthdBldr =
                    typeBuilder.DefineMethod("set_value",
                                               GetSetAttr,
                                               null,
                                               new Type[] { typeof(string) });

                // Again some Intermediate Language stuff...
                ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
                currSetIL.Emit(OpCodes.Ldarg_0);
                currSetIL.Emit(OpCodes.Ldarg_1);
                currSetIL.Emit(OpCodes.Stfld, field);
                currSetIL.Emit(OpCodes.Ret);

                // Last, we must map the two methods created above to our PropertyBuilder to 
                // their corresponding behaviors, "get" and "set" respectively. 
                property.SetGetMethod(currGetPropMthdBldr);
                property.SetSetMethod(currSetPropMthdBldr);
            }

            // Generate our type
            Type generetedType = typeBuilder.CreateType();

            // Now we have our type. Let's create an instance from it:
            object generetedObject = Activator.CreateInstance(generetedType);

            // Loop over all the generated properties, and assign the values from our XML:
            PropertyInfo[] properties = generetedType.GetProperties();

            int propertiesCounter = 0;

            // Loop over the values that we will assign to the properties
            foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
            {
                string value = node.InnerText;
                properties[propertiesCounter].SetValue(generetedObject, value, null);
                propertiesCounter++;
            }

            //Yoopy ! Return our new genereted object.
            return generetedObject;
        }

【问题讨论】:

  • 对我来说,类型创建本身有效,更多我无法测试。但是您必须将您的DefineMethod("set_value", 更改为DefineMethod("set_" + propertyName,,否则您将创建具有相同签名和名称的重复方法,这是非法的。

标签: c# asp.net asp.net-mvc reflection system.reflection


【解决方案1】:

发生这种情况是因为 RuleModel.Create(Type type) 在内部调用了 Assembly.Load(string assemblyName),后者在默认搜索路径中查找程序集,例如bin/、bin/assembly.dll/、.net 临时路径等。我希望它只使用传递的类型,但事实并非如此。它会尝试加载它。

请务必先调用 AssemblyBuilder.Save() 方法保存程序集,以便稍后由 RuleModel 加载。

How to use a dinamically generated object as the data source of CodeEffects generator查看我之前的回答

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2020-08-17
    相关资源
    最近更新 更多