在运行系统中加载程序集并调用方法并卸载程序集

时间:2011-06-25 12:06:30

标签: c#-4.0 appdomain dynamic-assemblies

我正在创建一个应用程序,它将连接到几个sql数据库并从数据库中获取一些细节,

在此应用程序中,我必须加密数据库连接详细信息,例如用户名密码。是的,它的直接和简单的pritty只是写一个metod来解密凭证。

但在我的情况下,我必须依靠第三方encription mechanisam来解密凭据。更多的我必须连接到几个sql服务器,这将再次使用一些其他加密方法。因此,我的应用程序动态加载加密程序集并调用加密方法。

但是当我加载程序集表单Assembly.LoadFile(“Path”)时,我无法卸载已加载的程序集。我想我已经在单独的应用程序域中加载此程序集并调用relavant方法并卸载该appdomain。我需要一些帮助。由于我缺乏knoladge,我无法调用所需的方法。我的代码如下。请帮帮我。

类ApplicationSettings     {

    private static ApplicationSettings m_ApplicationSettings;
    public String m_ServerName { get; private set; }
    public String m_DatabaseName { get; private set; }
    public String m_UserID { get; private set; }
    public String m_Password { get; private set; }
    public String m_EncryptionDLLPath{ get; private set; }
    public String m_NameSpace { get; private set; }
    public String m_ClassName { get; private set; }
    public String m_EncryptionMethodName { get; private set; }
    public String m_DecryptionMethodName { get; private set; }

    private ApplicationSettings()
    {
        m_ApplicationSettings = this;
    }

    public static ApplicationSettings CurrentValues
    {
        get
        {                
            return m_ApplicationSettings;
        }
        private set
        {
            m_ApplicationSettings = value;
        }
    }

    internal static void Initialize()
    {
        CommonFunctions.DataEncryption _enc = new CommonFunctions.DataEncryption();


        ApplicationSettings.CurrentValues = new ApplicationSettings();
        ApplicationSettings.CurrentValues.m_EncryptionDLLPath = @"C:\Users\Administrator\Documents\Visual Studio 2010\Projects\TestApp\TestApp\bin\Debug\AppSec.dll";
        ApplicationSettings.CurrentValues.m_NameSpace = "AppSec";
        ApplicationSettings.CurrentValues.m_ClassName = "AppSecEncDec";
        ApplicationSettings.CurrentValues.m_EncryptionMethodName = "Encrypt";
        ApplicationSettings.CurrentValues.m_DecryptionMethodName = "Decrypt";
        ApplicationSettings.CurrentValues.m_Password = _enc.Decrypt("pzBS3EJDoGM=");
        ApplicationSettings.CurrentValues.m_UserID = "sa";

    }



}

类DataEncryption     {

    AppDomain DomainName;        

    //Call the Encryption Method 
    public String Encrypt(Object _DataToEncrypt)
    {


    }

    //Call the Decryption Method 
    public String Decrypt(Object _DataToDecrypt)
    {
        String _Decrypt = "";

        String assemblyFileName = ApplicationSettings.CurrentValues.m_EncryptionDLLPath;
        String assemblyName = ApplicationSettings.CurrentValues.m_NameSpace;

        //Setup the evidence
        Evidence evidence = new Evidence(AppDomain.CurrentDomain.Evidence);
        AppDomain TestDomain = AppDomain.CreateDomain(
          "TestDomain", //The friendly name of the domain.
          evidence,   //Evidence mapped through the security policy to establish a top-of-stack permission set.
          AppDomain.CurrentDomain.BaseDirectory,  // The base directory that the assembly resolver uses to probe for assemblies.
          System.IO.Path.GetFullPath(assemblyFileName),    // The path relative to the base directory where the assembly resolver should probe for private assemblies.
          true  // If true, a shadow copy of an assembly is loaded into this application domain.
          );
        string s = TestDomain.Load(assemblyName).FullName;
        string[] myparam = new String[1];
        myparam[0] = "test";


        TestDomain.CreateInstance(TestDomain.Load(assemblyName).GetName().ToString(), ApplicationSettings.CurrentValues.m_NameSpace + "." + ApplicationSettings.CurrentValues.m_ClassName).CreateObjRef(GetType());
        //her i need to execute the Encrypt method which will load form the third party encryption mechanisam

        //method name will be returnd on this parameter in application settings Classes.ApplicationSettings.CurrentValues.m_EncryptionMethodName ;

        UloadAssembly();

        return _Decrypt;
    }


    public void UloadAssembly()
    {
        //Unload the loaded appdomain
        AppDomain.Unload(DomainName);            
        GC.Collect();
    }


}

提前致谢。

1 个答案:

答案 0 :(得分:0)

我已经想出如何做到这一点,并希望完全成功,请找到以下代码,如果用于过度的情况

       public String Encrypt(Object _DataToEncrypt)
    {
        try
        {

            String _Encrypt = "";
            LoadAssembly();
            ShowLoadedAssemblies();
            if (ClassInstance != null)
            {
                MethodInfo EncryptionMethod = ClassInstance.GetType().GetMethod(Classes.ApplicationSettings.CurrentValues.m_EncryptionMethodName); ;
                if (EncryptionMethod != null)
                {
                    object[] myparam = new object[1];
                    myparam[0] = _DataToEncrypt;
                    _Encrypt = (string)EncryptionMethod.Invoke(null, myparam);
                }

            }

            UloadAssembly();
            ShowLoadedAssemblies();
            return _Encrypt;
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);


        }

    }

    //Call the Decryption Method 
    public String Decrypt(Object _DataToDecrypt)
    {
        String _Decrypt = "";

        LoadAssembly();
        ShowLoadedAssemblies();
        if (ClassInstance != null)
        {
            MethodInfo DecryptionMethod = ClassInstance.GetType().GetMethod(Classes.ApplicationSettings.CurrentValues.m_DecryptionMethodName);;
            if (DecryptionMethod != null)
            {
                object[] myparam = new object[1];
                myparam[0] = _DataToDecrypt;
                _Decrypt = (string)DecryptionMethod.Invoke(null, myparam);
            }               

        }
        UloadAssembly();
        ShowLoadedAssemblies();
        return _Decrypt;
    }
    //Loading the Assembly 
    public void LoadAssembly()
    {




        Evidence evi = new Evidence(AppDomain.CurrentDomain.Evidence);

        DomainName = AppDomain.CreateDomain(Classes.ApplicationSettings.CurrentValues.m_NameSpace
                                            , evi
                                            , AppDomain.CurrentDomain.BaseDirectory
                                            , Classes.ApplicationSettings.CurrentValues.m_EncryptionDLLPath
                                            , true
                                            );

       String LoadingAssemblyName = AssemblyName.GetAssemblyName(Classes.ApplicationSettings.CurrentValues.m_EncryptionDLLPath).FullName;

       ClassInstance = DomainName.CreateInstanceAndUnwrap(LoadingAssemblyName
                                                           , Classes.ApplicationSettings.CurrentValues.m_NameSpace 
                                                              + "." 
                                                              + Classes.ApplicationSettings.CurrentValues.m_ClassName
                                                           );

    }
    public void UloadAssembly()
    {
        //Unload the loaded appdomain
        AppDomain.Unload(DomainName);            
        GC.Collect();
    }