Fornire un nome di assembly esplicito per una cartella App_Code del sito Web ASP.net compilato dinamicamente?

StackOverflow https://stackoverflow.com/questions/9520231

Domanda

In un progetto di siti Web ASP.NET compilato dinamicamente, il montaggio può essere esplicitamente il montaggio per la cartella App_Code?

Ad esempio, in circostanze regolari quando eseguo un sito Web ASP.NET, il nome del montaggio generato nella cartella Temporary ASP.NET Files\ è parzialmente randomizzato come App_Code.neizakfo.dll dove NEIZAKFO è la porzione che può differire. Posso fornire esplicitamente un nome per il montaggio come App_Code_Web1.dll?

Chiarimento

Per esigenze aziendali, il sito Web non può essere precompilato / distribuito. Pertanto, sto cercando una soluzione nel contesto della cartella Temporary ASP.NET Files e assemblee compilati dinamicamente come indicato sopra.


.

Sfondo :
Ho trovato questa domanda mentre cercavo un modo per eseguire un'istanza di tipo dinamica su una classe nella cartella App_Code di un sito Web utilizzando un nome qualificato da assembly memorizzato nella configurazione, ma istanziata dalla pagina Web, attraversando così un limite di assemblaggio. Poiché la pagina Web e il codice App_Code sono compilati in due diversi assembly per impostazione predefinita, il comportamento predefinito del metodo di tipo.GetType (..) di ricerca del nome del tipo nel gruppo di esecuzione corrente (la pagina Web) o in MSCorlib non Basta per raccogliere qualsiasi tipo dall'applicazione App_code. Essere randomizzati, il nome del gruppo APP_Code non è noto per me includere nella stringa qualificata da assembly.

Posso inserire il tipo di dati in una libreria di classe (perché ciò ha un nome predefinito / esatto) per sbarazzarsi di questo problema, tuttavia mi piacerebbe sapere come farlo all'interno del sito web stesso senza creare una classe Progetto della biblioteca per lo scopo.

È stato utile?

Soluzione

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 ;-)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top