Hosting a .net assembly for COM interop with long lifetime? - asp.net

I have a component (an assembly built in .net) that i need to access on (almost) every request to two different websites. One website is written in classic asp and the other one in asp.net mvc.
At the moment i reference the assembly in the asp.net solution and call it like i would any .net assembly. On the classic asp website, i call it through a COM wrapper.
This is all good, except now i need this component to actually stay alive and monitor changes to a configuration file. In my asp.net website i could keep a refence in the application scope and i guess i could register it in component services for the asp access.
Is this the best way to do it? Also, this way the component would actually be hosted twice - one instance in the asp.net application scope and one in the component services. I could perhaps instead only have it live in component services, and then instead reference it from asp.net.
I don't know - something smells fishy (and no, it's not me) - am i on the right track or do you see better alternatives?

Do you really need a long running object? You say you need to monitor configuration file changes -- when the config changes do you need to trigger some actions or do you just need to ensure that each incoming request uses the latest copy of the configuration for your component? If it is the latter then standard .NET configuration should work for you without concern for the object lifetime.
In terms of hosting, do you need to use any COM+ services? If not, then I would not use COM+. If you want one central location for your .NET component, why not register it in the GAC?

Ok so i think i found two solutions, both acceptable for this project:
1) Register it in global.asa on the Application_OnStart in the Application object like this Application("Someobject") = Server.CreateObject("Someobject")
2) Host it in component services and handle lifetime there.

Related

Vanilla ASP.NET and REST

I wish to implement REST service which will be integrated with ASP site (basically the same project).
I've tried to provide my custom VirtualPathProvider (VPP) and it works, but to a certain degree. First, the content-type of the response is always application/octet-stream. Second, only GET requests are piped through the VPP. I've seen people playing around with HttpApplication to solve these problems. I am not sure if I wish to follow the path of hacking the ASP as it might take a lot of time, and in the end it might be simply impossible to accomplish the task.
Is there a way to do it, or I should create a separate page for MVC, and talk with it via some inter-process communication. This way MVC will be handle the REST requests and call my code in response. And vice versa - ASP will be able to send REST requests to remote servers.
If there are any other, cleaner, safer & easier, ways of linking MVC with vanilla ASP, then feel free to post them in comments/answers.
VirtualPathProvider is meant to be a way to virtualize the filesystem for internal ASP.NET operations (e.g. storing *.aspx and *.master files in a database), it is only coincidental that it works for user-provided URIs and requests.
Your best bet is just to use ASP.NET MVC, which is now integrated with ASP.NET (since 4.x) or as an easily redistributable component in .NET 3.x. ASP.NET MVC does play nice with WinForms in the same application, so don't reinvent the wheel.
However, if you are insistent, the only real option is to do it all from within a custom IHttpHandler that chooses to handle incoming requests or not (as you won't have ASP.NET URL Routing because you're not using ASP.NET MVC).

Host 'n' number of SignalR hubs in ASP.NET (but MEF'd in)

I have an ASP.NET web project where I need to host a number of SignalR hubs that another MVC3 application will talk to.
My main problem is that I don't know until runtime which Hubs I will be hosting as they need to be MEF'd in. The DLLs containing the exports (of type IXXXHub) will be in the bin directory of the ASP.NET web site. At the moment there are 3 exportable types - AHub, BHub and CHub but there could be more, e.g. DHub may be implemented later.
I've gone through the SignalR sample showing how to host in an ASP.NET web project so the part I'm confused about is trying to get mine MEF'd in and host one of each of AHub/BHub/CHub. I've looked at various approaches using Application_Start but couldn't work out how.
Does anyone have an idea?
I got the answer in the end by just having the [ImportMany] attribute on a List object in the Global.asax class and then having the MEF catalog/container/ComposeParts code in the Application_Start function.

System.Addin - Creating secured ASP.NET MVC plugins

Lately my focus has been on creating an ASP.NET MVC application that can host 3rd party MVC plugins. Ideally, development of those plugins would follow these rules:
Plugins can be developed in a standard MVC project, and be able to use all the existing infrastructure of the ASP.NET MVC framework.
The complexity of compiling the plugin MVC project and including into a host MVC application should not be severe.
Any changes to the normal development flow of an MVC application would be the bear minimum
After some research I've come up with the following approaches to achieve this, each with their own advantages and disadvantages.
Approach 1 - MVC plugin assembly loaded into main MVC AppDomain
Work Flow
Develop plugin inside a separate MVC project.
Compile the assembly and load it and any dependencies into the host application via PreApplicationStartMethodAttribute, MEF or a basic assembly reference within the host project (if possible).
Map a route to the plugin controllers so that the plugin is treated as an Area within the host.
Place the plugin views into the correct area folder. The layout file will need to be changed so that the layout path points to an area based location, rather than the root of the application (which would have been the case in the development MVC project)
When a request comes in for the plugin, ASP.NET will use the existing areas functionality to route the request to the correct controllers and look in the correct location for the view files.
Advantages
Will work as seamlessly as if the controllers were embedded in the host MVC application assembly.
Simple to include the assemblies into the host App Domain before application start (PreApplicationStartMethodAttribute, project reference) and after application start (MEF)
Disadvantages
No sandboxing - the controllers will have the same trust level as host.
Conclusion
This is the easiest approach, however it is also the least secure. It essentially removes the possibility of allowing untrusted developers to create plugins because those plugins will have the same trust level as the host application (meaning that if the host application can execute methods such as System.IO.File.Delete, so can the plugin)
Approach 2 - MVC plugin assembly running in own AppDomain via MAF
This approach intends to allow the creation of MVC plugins that can be sandboxed into their own AppDomains and used by the host via the System.Addin libraries.
Structure
A route is setup in the host that determines whether the url being processed is targeting a plugin. May have a pattern such as example.com/p/{plugin}/{controller}/{action}/{id}
All routes that have the above pattern are mapped to a host controller that has a module routing action. That action looks at any given route and determines the appropriate plugin to process the request based on the {plugin} segment.
The plugin view is a receiver/sender object that acts as a gateway to the plugin controllers. It has a method called AcceptRequest that receives a RequestContext from the host, and that returns an ActionResult.
The plugin pipeline contains adapters that can serialise RequestContext and ActionResult for transmission across the isolation boundary of the pipeline.
Execution Flow
A route for a plugin is matched and the plugin routing controller is called.
The controller loads the required plugin into it's own AppDomain and calls AcceptRequest, passing through the RequestContext (which is serialised via the pipeline)
AcceptRequest receives the context and determines the appropriate controller to execute based on that request (using a custom controller factory).
Once the controller has finished executing the request, it returns an ActionResult to the receiver object which then passed that ActionResult (also serialised via the pipeline) back to the host AppDomain.
The controller that initially called AcceptRequest can then return the ActionResult to the host MVC execution pipeline, as if it processed the request itself. The plugin AppDomain can then be unloaded if so wished.
Advantages
Plugin will be sandboxed in it's AppDomain, thus any permission set can be used that suits the host.
Disadvantages
Would have to be possible to serialise RequestContext and ActionResult.
Will possibly break other ASP.NET MVC functionality within the isolated AppDomain.
Conclusion
This approach sounds good on paper, but I'm not sure if it's possible/feasible to serialise the RequestContext and ActionResult objects, as well as run an MVC controller in isolation.
Questions
The first approach is fine if the code is being created by trusted developers. I know that I'm not going delete all the host view files or it's web.config file. But ultimately, if you want third party devs to create plugins for your MVC app, you need to be able to sandbox their code.
From all my research, the System.Addin library makes it easy to implement a host/plugin environment when you are using simple API based class libraries. However it seems that it isn't easy to do this when MVC is involved.
Some questions I have are:
Is the second approach I've outlined here feasible?
Is there a better way to do this?
Is there going to be easier ways to achieve MVC plugin isolation in the future?
You're going to end up making separate sites for each plugin. This way you can create reduced-privilege users for each AppPool and a systems administrator can install the "plugin" as a website running under that user.
Any alternatives are going to exhibit the Inner Platform antipattern. Unless you have a lot of time and money to spend developing a plugin-hosting system, you're going to become mired in it and resent it. I speak from experience.
The sites can share AspnetIdentity user repos and you can provide your core objects as a dll that can be referenced. Host your content (script files, css, images) on a CDN so they can be referenced. If you want to share views with your child sites, compile them in as resources:
Including Pre-Compiled Views in an ASP.NET MVC Web Application
Good luck!
IMHO System.AddIn is a a bit overkill for what you are trying to do.
Are you familiar with the System.Security.Permissions namespace? If not you could have a look at the FileIOPermission. Perhaps you could sandbox your extensible system by using (and why not, even extending) the Code Access Security mechanism of .NET.

writing azure-friendly asp.net

I'm building an asp.net application that will be deployed on Azure. For the moment, I'm using regular asp.net: I'm building it in VS.
I have a web service that's in an asxm file MyService.asmx with a code behind file MyService.cs that calls a different class library called MyBigClass.cs that does most of the work.
If I want to prepare for a deployment on Azure in a few months and make that web service work in its own web role that I can scale based on usage load, should I put the classes that are in the MyBigClass.cs file into the MyService.cs file? The MyBigClass.cs file contains classes that are used for other parts of the application as well; should I remove these classes and only include the ones used by the web service?
Thanks.
Difficult to give a specific answer, and to be honest - I don't think the answer to this would be Windows-Azure-specific, but rather - this is simply a design best practice question, isn't it?
It comes down to how you will go about maintaining the application, and how you are going to manage versioning, but generally speaking - code that isn't shared does not need to get deployed to both roles, so either move it back with the 'parnet' solution (web app or service), or keep in a separate assembly which you will deploy with only the relevant role.
Code that is shared between the web app and service will exist in a shared assembly which you will deploy into both roles.
So you might end up with the following projects
A web site
An assembly supporting the web site
A Web service Service
An assembly supporting the web service
A shared assembly between the web site and web service
I hope this makes sense

6-month migration path from asp to asp.net - is it worth interopping?

I'm going to migrate from asp to asp.net over the next few months. Is it worth building .NET interop components and calling them through COM wrappers in ASP to move things along? If so - what types of components would you make? Data access? It's largely a CRUD and reporting application.
I wouldn't go down the COM path. Considering both apps are web based and the type of operations or transaction are fairly standard, I suggest you look at web services rather than com object and building throwing away wrappers. These web services can immediately be consumed as building block in your new ASP.NET application project too.
It's worth doing but go directly to ASP.NET MVC, it is most similar to Classic ASP style than regular .NET
I'm doing something similar but not a full migration. I decided to go the COM route so that I could take advantage of .NET while still having reusable components down the road in case a full rewrite were to become necessary. The COM route is pretty straight forward and is very trivial to glue into ASP code. I would recommend it if you want to build a piece at a time.
In my case I made some Active Directory components and some other general purpose ones.

Resources