在应用程序重新启动时清除临时ASP.NET文件

时间:2012-03-20 11:35:09

标签: asp.net asp.net-mvc plugins iis-express

我们在启动时动态加载程序集并将其添加为参考:

BuildManager.AddReferencedAssembly(assembly);

该应用程序支持在运行时安装新插件。在安装/卸载操作之后,我们将重新启动Web应用程序。我试过了:

HostingEnvironment.InitiateShutdown();

System.Web.HttpRuntime.UnloadAppDomain();

然而,新版本的插件未加载 - 我相信这是由于ASP.NET如何积极地缓存引用的程序集 - 尤其是ASP.NET MVC控制器。

在生产中,这不应该是一个问题,因为插件程序集版本每次都会增加。但是,在开发过程中,这是一个更大的问题,因为我们不希望每次对插件稍作更改时都要更改版本号。

我们如何以编程方式或使用post build事件强制清除临时asp.net文件?

一个解决方案是"触摸" global.asax,但这对我来说似乎有些苛刻。

1 个答案:

答案 0 :(得分:1)

我已经使用以下代码来按需重置应用程序池。 (只需将其连接到Controller Action)。

注意:由于它是应用程序池,您可能需要检查对同一应用程序池上运行的任何其他应用程序的影响。

public class IisManager
{
    public static string GetCurrentApplicationPoolId()
    {
        // Application is not hosted on IIS
        if (!AppDomain.CurrentDomain.FriendlyName.StartsWith("/LM/"))
            return string.Empty;
        // Application hosted on IIS that doesn't support App Pools, like 5.1
        else if (!DirectoryEntry.Exists("IIS://Localhost/W3SVC/AppPools"))
            return string.Empty;

        string virtualDirPath = AppDomain.CurrentDomain.FriendlyName;
        virtualDirPath = virtualDirPath.Substring(4);
        int index = virtualDirPath.Length + 1;
        index = virtualDirPath.LastIndexOf("-", index - 1, index - 1);
        index = virtualDirPath.LastIndexOf("-", index - 1, index - 1);
        virtualDirPath = "IIS://localhost/" + virtualDirPath.Remove(index);
        var virtualDirEntry = new DirectoryEntry(virtualDirPath);
        return virtualDirEntry.Properties["AppPoolId"].Value.ToString();
    }


    public static void RecycleApplicationPool(string appPoolId)
    {
        string appPoolPath = "IIS://localhost/W3SVC/AppPools/" + appPoolId;
        var appPoolEntry = new DirectoryEntry(appPoolPath);
        appPoolEntry.Invoke("Recycle");
    }

    public static void RecycleApplicationPool(string appPoolId, string username, string password)
    {
        string appPoolPath = "IIS://localhost/W3SVC/AppPools/" + appPoolId;
        var appPoolEntry = new DirectoryEntry(appPoolPath, username, password);
        appPoolEntry.Invoke("Recycle");
    }

}

重写的方法是为了满足您希望在托管IIS实例的计算机/服务器上显式传递具有管理员权限的用户的实例。

控制器动作可能类似于;

 public string ResetAppPool()
    {
        var appPoolId = IisManager.GetCurrentApplicationPoolId();
        if (appPoolId.Equals(string.Empty))
            return "Application is not running inside an App Pool"; //May be not IIS 6 onwards
        try
        {
            IisManager.RecycleApplicationPool(appPoolId); //Can only be used by Admin users
            return string.Format("App pool {0} recycled successfully", appPoolId);
        }
        catch (Exception ex)
        {
            Logger.Error("Failed to recycle app pool : " + ex.StackTrace);
            return string.Format("App pool {0} recycle failed", appPoolId);
        }
    }