[Plug-in framework Exploration Series] application domain (appdomain)

Source: Internet
Author: User

ApplicationProgramDomain (appdomain) is no longer a new term. As long as anyone familiar with. Net knows its existence, we should first get to know the application domain again, and find out where it is.

Application domain

As we all know, the process isCodeThe smallest unit for execution and resource allocation. Each process has an independent memory unit, and processes are isolated from each other. Naturally, processes become the security boundary for code execution.

A process corresponds to an application. net breaks this Convention because it brings a brand new concept of application domains. CLR can use application domains to provide isolation between applications, A process can run multiple application domains, that is, as long as the application domain is used, we can run multiple applications in a process, this does not cause additional overhead for inter-process calls or inter-process switching.

Do you think the application domain is amazing? Don't worry. Let's take a look at what its isolation feature has brought to us.

Advantages

First, application domains do not affect each other. It is a natural exception isolation mechanism. That is to say, errors in one application domain will not affect other application domains, because type-safe code will not cause memory errors.

Secondly, it can dynamically load and uninstall the Assembly at runtime. We all know that. in the net world, once the loader loads the Assembly, it will remain in the entire lifecycle of the application, and the application domain changes all of this, it provides us with the ability to uninstall an assembly.

Finally, the application domain can separately implement security policies and configuration policies. To put it bluntly, you can configure permissions for each application domain to better manage applications.

In addition, there is no one-to-one correlation between application domains and threads. At any given time, multiple threads can be executed in a single application domain, and a specific thread is not limited to a single application domain. That is to say, the thread can freely cross the application domain boundary. If there is no active startup thread, then multiple application domains will still run in the same thread.

In general, application domains form the isolation, uninstallation, and security boundaries of managed code. These features provide a plug-in framework with exception isolation, dynamic loading and unloading of plug-ins, and a safer runtime environment for plug-ins.

Because of thisArticleThe positioning of the framework is based on the characteristics of the application domain. Therefore, if you have a certain understanding of the application domain, the following uses an example, let's take a step-by-step look at these features of the application domain.

Create and uninstall an appdomain

Using C #, we can create an application domain in the following way and execute a piece of code in the new domain:

  Appdomain  = Appdomain. createdomain (  "  Hello appdomain!  "  );

Domain. docallback ( New Crossappdomaindelegate (() =>

{

Window win = New Window

{

Width = 300 ,

Height = 100 ,

Content = Appdomain. currentdomain. friendlyname

};

Win. Show ();

}));

 

 

After running, the window created in the new domain is displayed as follows:

 

The appdomain static method appdomain. Unload (domain) can be used to uninstall the application domain, which is so simple.

Configure the domain Loading Method

If you run the above Code, do you find that the window created by the new domain has been displayed for a long time? What is the problem? Simply put, this is because. by default, the net loader reloads the referenced assembly (including the Assembly except mscorlib of the Framework) in each domain. Of course, we can change this behavior, but before that, let's take a look at the next new concept"Domain neutrality"For more information, see this article domain neutral assemblies. In short, it has the capability of cross-origin shared assembly, which avoids the loss of repeated loading, you can add the loaderoptimization label to the main function of the program entry to modify the default Loading Mode:

 

   code highlighting produced by actipro codehighlighter (freeware) 
http://www.CodeHighlighter.com/
--> [system. stathreadattribute ()]
[system. diagnostics. debuggernonusercodeattribute ()]
[loaderoptimization (
loaderoptimization. multidomainhost)]
Public static void main ()

{< br>
appdomaintest. APP = New appdomaintest. APP ();
app. initializecomponent ();
app. run ();

}< br>

 

 

Recompile and run the program. The speed has been significantly improved.

Loaderoptimization has three methods (Singledomain, multidomainAndMultidomainhost) In domain neutral assemblies, there are detailed interpretations. If you are interested, you can read them and I will not repeat them here.

Exception isolation 

Exception isolation is very important for plug-in frameworks, which is a necessary feature to ensure the stability of a framework. Next, let's take a look at how to implement exception isolation using application domains.

First, we will simulate throwing an exception in the newly created domain:

 

  Appdomain  =  Appdomain. createdomain (  " Hello appdomain!  "  );

Domain. docallback ( New Crossappdomaindelegate (() =>

{

Window win = New Window

{

Width = 300 ,

Height = 100 ,

Content = Appdomain. currentdomain. friendlyname

};

Win. Loaded + = (OBJ, ARG) =>

{

Throw New Exception ( " Test exception. " );

};

Win. Show ();

}));

 

 

Here, we use the window loaded event to directly throw an exception to achieve the Simulated effect. OK, compile and run it. Unfortunately, it is successfully suspended.

This is because unhandled exceptions in the new domain are eventually thrown to the default domain, resulting in a crash. To verify this, we only need to add the appdomain in the default domain. currentdomain. the unhandledexception event processing can intercept the exceptions thrown in the new domain. Unfortunately, you can only intercept the exceptions but cannot change the crash result.

Then how can we handle this exception? register the system. Windows. Threading. Dispatcher. currentdispatcher. unhandledexception event in the default domain or new domain to handle it, as shown in the following example:

 

  Appdomain  =  Appdomain. createdomain (  "  Hello appdomain!  "  );
System. Windows. Threading. Dispatcher. currentdispatcher. unhandledexception + = (OBJ, ARG) =>
{
Arg. Handled = True ;
MessageBox. Show (Arg. Exception. Message );
Appdomain. Unload (domain );
};
Domain. docallback ( New Crossappdomaindelegate (() =>
{
Window win = New Window
{
Width = 300 ,
Height = 100 ,
Content = Appdomain. currentdomain. friendlyname
};
Win. Loaded + = (OBJ, ARG) =>
{
Throw New Exception ( " Test exception. " );
};
Win. Show ();
}));

 

 

Note the most critical Arg. handled = true indicates that the event has been handled by the system. Do not pass it down, and finally take the initiative to unmount the new domain, the default domain is still running normally, thus achieving exception isolation.

Combination of plug-ins in different domains 

Assuming that all the plug-ins are in different domains, how can we combine them? That is, how can we present the plug-ins in different domains to a container at the same time.

As we all know, objects must be serializable or inherited from the marshalbyrefobject type to implement object transfer between domains. However, the UI control is powerless, this requires the help of Microsoft's addin framework. Although everyone thinks that the addin framework is complex and difficult to use, there are some useful things in it, such as the frameworkelementadapters class to be used here, it provides two static methods, contracttoviewadapter and viewtocontractadapter, for mutual conversion between frameworkelement and inativehandlecontract. It is said that such conversion is implemented through the handle. Let's use examples to illustrate how to make the plug-in cross-origin presentation. First, add the system. addin. Contract. dll and system. Windows. Presentation. dll references, and then write the following code:

 

  Appdomain  =  Appdomain. createdomain (  "  Test  "  );
Domain. docallback ( New Crossappdomaindelegate (() =>
{
// Create a button control in the new domain
Button BTN = New Button {content = " Test " };
// Convert the button control to inativehandlecontract.
Inativehandlecontract ICT = Frameworkelementadapters. viewtocontractadapter (BTN );
Appdomain. currentdomain. setdata ( " Testbtn " , ICT );
}));
// Obtain the inativehandlecontract object in the new domain in the primary domain.
Inativehandlecontract icontract = Domain. getdata ( " Testbtn " ) As Inativehandlecontract;
// Convert inativehandlecontract object back to frameworkelement
Frameworkelement CTRL = Frameworkelementadapters. contracttoviewadapter (icontract );
Application. Current. mainwindow. Content = CTRL;

 

 

The running result is as follows. The control created in the new domain is successfully displayed in the primary domain.

 

The permission configuration section in the domain will be described in the next article.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.