Provide an Explicit Assembly Name for a Dynamically Compiled ASP.NET Website's App_Code Folder?

瘦欲@ 提交于 2020-01-04 05:04:25

问题


In a dynamically compiled ASP.NET Website project, can the assembly for the App_Code folder be explicitly named?

For example, under regular circumstances when I run an ASP.NET website the assembly name generated into the Temporary ASP.NET Files\ folder is partially randomized like App_Code.neizakfo.dll where neizakfo is the portion that can differ. Can I explicitly provide a name for the assembly like App_Code_Web1.dll?

Clarification

By business requirements, the website cannot be precompiled/deployed. Therefore I'm seeking a solution in context of the Temporary ASP.NET Files folder and dynamically compiled assemblies as noted above.


Background:
I came across this question while looking for a way to perform dynamic type instantiation on a class in the App_Code folder of a website using an assembly-qualified name stored in configuration, but instantiated from the web page, thus crossing an assembly boundary. Because the web page and app_code code are compiled into two different assemblies by default, the Type.GetType(..) method's default behaviour of searching for the Type name either in the current executing assembly (the web page) or in mscorlib doesn't suffice for picking any Type from the App_Code assembly. Being randomized, the app_code assembly name is not known for me to include in the assembly-qualified string.

I can put the data Type in a class library (because that does have an predefined/exact name) to get rid of this problem, however I'd like to know how to do this inside the website itself without creating a class library project for the purpose.


回答1:


You can sort of do this in a WebSite project.

There's an MSDN article on using the -fixednames flag when compiling the project.

This effectively creates an assembly for each page - default.aspx.dll. However, this is only marginally more useful to you as you still need to know the name of the control or page you are looking for when you are loading - so you have to ensure your types and naming is consistent. It should, however, respect the name of the classes in app_code so this may work for you.

One other thing you could do is move all of the code in app_code out into it's own assembly, and then add that as a project reference. That would also simplify this problem.

Lastly, you could enumerate all of the dll's in the bin directory, and search each one for the type you are looking for. As this is fairly expensive, do it once, and cache the result somewhere so you don't keep doing it everytime you look that type up. This is probably the worst solution.

This is trivial to do in a WebApplication project, but I assume you are stuck with the WebSite one?

EDIT: As an update for the comments; if I use the Publish Web Tool, then all of the code in app_code goes in the bin directory in a dll called App_Code.dll - this behaviour does not change even if I use fixed naming (all fixed naming effects the naming of the dll's for each page, usercontrol). If I use ILSpy on this file, I can see my classes in there. So I know the name of the assembly, and it's location - I should be able to get at the types in it with minimal effort. I wonder why I'm seeing different behavior to you!

I created a simple class called "Person" with an Id and Name, put it in App_Code, compiled the site, and then ran the following code:

  Type myType = Assembly.LoadFrom(Server.MapPath("~/bin/App_Code.dll")).GetType("Person", true);
  Response.Write(myType.ToString());

It wrote out "Person", as expected.

Further Edit

The penny drops! If I then do:

  object myObject= Activator.CreateInstance("App_Code.dll", "Person");

And try to cast myObject to person, I get the following message:

The type 'Person' exists in both 'App_Code.dll' and 'App_Code.jydjsaaa.dll'

So it's time to be devious.

in Global.asax, on Application_OnStart, do the following:

Application["App_Code_Assembly"] = Assembly.GetAssembly(typeof(Person));

In my test default page, I then did:

  Assembly app_Code = Application["App_Code_Assembly"] as Assembly;
  Response.Write(app_Code.FullName);

Which gave me the randomly named app_code it is actually running with in Temporary ASP.Net Files.

This is why I hate Web Site Projects ;-)



来源:https://stackoverflow.com/questions/9520231/provide-an-explicit-assembly-name-for-a-dynamically-compiled-asp-net-websites-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!