where should inheritance classes be stored? - asp.net

I want to create classes that can be inherited by other classes to use along my project.
i.e. i want to create a separate class for each Mail method, each class will implement differently the Compose method, and more Mail classes will be created in the future.
My question is - Where should I create these classes/interfaces? in the App_Code ?

I would suggest creating a separate assembly and include that assembly as a reference in your Web Project. That will enable you to write independent test cases against your classes / interfaces.

Other than user controls you can store source files in App_Code. In your case you can store Interfaces/classes in App_Code. You can have multiple folders for group of class/interfaces inside the AppCode.
AppCode
You can store source code in the App_Code folder, and it will be
automatically compiled at run time. The resulting assembly is
accessible to any other code in the Web application. The App_Code
folder therefore works much like the Bin folder, except that you can
store source code in it instead of compiled code. The App_Code folder
and its special status in an ASP.NET Web application makes it possible
to create custom classes and other source-code-only files and use them
in your Web application without having to compile them independently.
Edit: You may see this discuss: How to organize ASP.NET app_code folder?

Related

References and external class use problems

Using Visual Studio 2015 on an ASP.NET project. Everything works fine except now I have a block of code (A common AD utility function) that I want all the pages to be able to access. The original language (inherited project) is VB.NET, but it should work just fine either way.
I created a class file, named it CommonADFunctions.vb. The file uses System.DirectoryServices, and there's a reference in the project to that assembly. However, there are two problems:
I can't reference the new class to call the functions from any of the page code files. This includes attempts to instantiate a new variable as the class type.
When I move the new .VB file into App_Code, the reference to System.DirectoryServices breaks, and it refuses to build.
This may seem like a trivial ask, but what am I missing?
Turns out this was a simple property on the file itself I created a new Class File, and somehow the Build Action got set to Content rather than Compile. Setting this to Compile allowed the object to be referenced and instantiated properly. It doesn't fix the IDE intelliSense from APP_Code for DirectoryServices references in the code, but it compiles and runs, which is what I needed.
EDIT: Received external help which pointed this out.
Without code and screenshots to illustrate I can only recommend a few things to try.
I can't reference the new class to call the functions from any of the page code files. This includes attempts to instantiate a new variable as the class type.
The methods in the class have Private or Friend scope.
Its a static class (a Module in VB.Net) and you do not need to instantiate it.
You are somehow referencing an old DLL which doesn't have the methods. Check the reference to this AD project and make sure its "Referenced" via Project.
When I move the new .VB file into App_Code, the reference to System.DirectoryServices breaks, and it refuses to build.
This sounds like a corrupt project file. Clean the solution, delete the .suo file, delete the obj & bin folders.
Then move the CommonADFunctions.vb to the App_Code folder and add the DLL reference to System.DirectoryServices. Or create the CommonADFunctions.vb file in App_Code to start with.

converted web site to web application, works without namespaces

I converted a web site project to a web application using this guide
http://msdn.microsoft.com/en-us/library/aa983476%28v=vs.100%29.aspx
In the guide it says that I have to add namespaces to my classes but I did not do that. The classes I have in the Old_App_Code directory are not placed into namespaces and the application runs just fine (tested on different machines). Is it because there is something special about Old_App_Code or am I missing something? Thanks.
You are misinterpreting what the guide is saying, it is NOT saying that you need to add namespaces to get the code to compile, but rather that the conversion process does not add the namespaces into the code files by using the folder/file naming constructs.
The guide is further underscoring the fact that when you add new items (i.e. classes) in a web application versus a web site; the namespace is automatically added to the code file, based upon the folder structure and file name of the of new class.

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

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

Segregating to 3 tiers from existing ASP.NET project

In my asp.net project currently i have business logic and and data access code in two sub folders(BLL,DAL) which are itself located web site project's app_code folder. I need to segregate them to two separate projects(one project for business layer and one project for Data access code).
How can I maintain connection strings necessary to Data access project which are currently in web.config file?(i.e if I choose Class library template for creating DAL and BLL projects)
How can I maintain various other web.config key values that are currently used in BLL, DAL code files?
How can I deploy compiled project? (ie Web site project I am currently deploying bin folder to Staging> production but this way where should i put DAL.dll and BLL.dll and relevant config files)
1 and 2) Add a 'using System.Configuration' and just reference them. Since their referenced in the project, asp.net will pick it up.
For example:
using System.Configuration;
namespace DataLayer
{
public class BaseDataAccess
{
public static string ConnectionString_Logging
{
get
{
return ConfigurationManager.ConnectionStrings["ConnectionString_Logging_Legacy"].ToString();
}
}
}
}
3) If properly referenced, upon compile, your BLL and DAL dlls will be in your bin folder of the main/ui project. If using web.config, your good to go.
Fundamentally, you should be wrapping those configuration bits up in objects along the way. But in any case, you can move them to a different class project without worry here -- it will pick up the configuration settings from whatever project it is hosted by, so you don't need to somehow provide the configuration to your library.
Your existing code should work, as the settings are read from the Config file of the running process, in this case your Web.Config, however i suggest you use custom configuration settings, these would be read from your Web.Config file, a typical implementation could look something like :
<YourCompany>
<YourCompany.ProjectName>
<Data ConnectionName="NameOfConnectionToUse" SomethingElse="XZY" />
<Business SomeValue="12345" />
</YourCompany.ProjectName>
</YourCompany>
Without getting into ideal settings/custom config etc, as asked - during runtime, your class libraries will get the configuration from the web.config if referenced as such from within these layers with no change. System.Configuration.AppSettings/ConnectionStrings will still work.

Does App_Code in ASP.Net compile new code to a secondary temp AppDomain?

I am trying to better understand how the App-Code folder operates, and in particular I am curious how new objects that a new class in the App-Code folder are included in the current AppDomain. Is a second, temporary AppDomain created in the same manner as when I compile new objects with the CodeDom?
In many ways the capability of moving new classes / objects into a Web Application is very compelling. Rob Connery's MVC Storefront is a good illustration. If you have used the App-code folder to deploy new functionality were there any trade-offs or gotchas that should be considered?
UPDATE:
I found an article in CoDe Magazine with this interesting passage:
Your application-specific code can go
inline of the ASPX page or control, it
can go into a CodeBeside partial
class, or you can create completely
autonomous classes in the APP_CODE
folder. The APP_CODE folder is a
special folder in an ASP.NET 2.0
project and any non-page or
control-related source code in your
Web project must go into this folder.
ASP.NET treats the content of APP_CODE
like a library project and compiles
the content into a separate assembly.
This assembly is then referenced by
all of the page or directory-level
assemblies that ASP.NET creates from
your ASPX/ASCX pages that use any of
the classes defined in APP_CODE.
My question still stands - is a second AppDomain created that supports this libary, and if so are the impacts on performance minimal?
I don't know the details, but it will certainly be in different dynamic assemblies. A class can't be in another AppDomain. Only an instance of a class can be in another AppDomain, and then it's really a hassle to access from another AppDomain (only through remoting)

Resources