zoukankan      html  css  js  c++  java
  • C# Inject

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace System
    {
        partial class App
        {
            private class InjectItem
            {
                private ConcurrentDictionary<Guid, Assembly> _mapper;
    
                public AppDomain Domain { get; private set; }
                public ConcurrentDictionary<Guid, Assembly> Mapper
                {
                    get { return _mapper; }
                }
    
                public InjectItem(AppDomain domain)
                {
                    this.Domain = domain;
                    _mapper = new ConcurrentDictionary<Guid, Assembly>();
                }
            }
    
            private static SynchronizedCollection<InjectItem> _injectSet = new SynchronizedCollection<InjectItem>();
    
            private static InjectItem CallInject(string domainName)
            {
                if (_injectSet == null)
                {
                    var set = new SynchronizedCollection<InjectItem>();
                    set.Add(new InjectItem(AppDomain.CurrentDomain));
                    Interlocked.CompareExchange(ref _injectSet, set, null);
                }
                if (string.IsNullOrEmpty(domainName))
                {
                    return _injectSet.First();
                }
    
                domainName = string.Format("_{0}", domainName);
                var q = from t in _injectSet
                        where t.Domain.FriendlyName == domainName
                        select t;
                var item = q.SingleOrDefault();
                if (item == null)
                {
                    _injectSet.Add(item = new InjectItem(AppDomain.CreateDomain(domainName)));
                }
                return item;
            }
    
            public static Assembly Inject(Guid checksum, object arg, Stream rawStream = null, string domainName = null)
            {
                Contract.Requires(checksum != Guid.Empty);
    
                var item = CallInject(domainName);
                if (rawStream != null)
                {
                    var raw = new MemoryStream();
                    rawStream.FixedCopyTo(raw);
                    raw.Position = 0L;
                    Guid checksumNew = CryptoManaged.MD5Hash(raw);
                    if (checksum != checksumNew)
                    {
                        throw new InvalidOperationException("checksum");
                    }
                    return item.Mapper.GetOrAdd(checksum, k => item.Domain.Load(raw.ToArray()));
                }
                Assembly ass;
                if (!item.Mapper.TryGetValue(checksum, out ass))
                {
                    throw new InvalidOperationException("checksum");
                }
                Type entryType = ass.GetType(string.Format("{0}.Program", ass.FullName), false);
                if (entryType == null)
                {
                    var eType = typeof(IAppEntry);
                    var q = from t in ass.GetTypes()
                            where t.IsSubclassOf(eType)
                            select t;
                    entryType = q.FirstOrDefault();
                }
                if (entryType != null)
                {
                    var creator = entryType.GetConstructor(Type.EmptyTypes);
                    if (creator != null)
                    {
                        var entry = (IAppEntry)creator.Invoke(null);
                        try
                        {
                            entry.Main(arg);
                        }
                        catch (Exception ex)
                        {
                            LogError(ex, "Inject");
    #if DEBUG
                            throw;              
    #endif
                        }
                    }
                }
                return ass;
            }
    
            public static void Uninject(string domainName)
            {
                Contract.Requires(!string.IsNullOrEmpty(domainName));
    
                var item = CallInject(domainName);
                _injectSet.Remove(item);
                try
                {
                    AppDomain.Unload(item.Domain);
                }
                catch (Exception ex)
                {
                    LogError(ex, "Uninject");
    #if DEBUG
                    throw;
    #endif
                }
            }
        }
    }
  • 相关阅读:
    “大型票务系统”和“实物电商系统”在恶意订单方面的差别与联系
    Eclipse_java项目中导入外部jar文件
    03007_JDBC概述
    微笑心灵“医”路 -- 09级临床医学雷林鹏访谈实录
    雷林鹏:一个90后草根创业者的野蛮生长
    关于hugepages 3.txt
    人物专访:全面发展的企业家——雷林鹏
    热备模式相关问题2.txt
    农林苗木人物专访:雷林鹏 追求本质
    热备模式相关问题2.txt
  • 原文地址:https://www.cnblogs.com/Googler/p/3746223.html
Copyright © 2011-2022 走看看