2016-05-26 5 views
1

Я работаю над приложением ASP.NET, и мы хотим добавить возможность вызова сценария клиента во время некоторых запросов. Поскольку мы не доверяем этому сценарию, мы создаем дочерний AppDomain внутри нашего запроса IIS, который имеет ограниченные разрешения и загружает сборку клиента и сборку Script Runner. Сценарий клиента может делать такие вещи, как изменение описания бизнес-объекта или изменение кода состояния на ошибку, если выполняются определенные критерии. Поскольку изменения настолько разнообразны, я не могу охватить их в одном объекте, который возвращается из вызова метода. По мере запуска скрипта мне нужно изменить значения в объектах внутри запроса, который запустил этот дочерний элемент.Двусторонняя связь между AppDomains внутри запросов IIS

Этот post рекомендует использовать NetNamedPipeBinding, но я все время опасаюсь, что он не подходит для кода, запущенного внутри IIS, где несколько запросов могут выполняться одновременно. Могу ли я настроить новый хост для каждого запроса IIS? Настроить статический хост для всего процесса, а затем использовать конечные точки, чтобы убедиться, что правильный ребенок говорит с правильным запросом? Это правильная технология?

Если это не правильная технология, что это такое? Этот post рассказывает вам, как получить дескриптор родительского AppDomain, но многие из них, похоже, используют mscoree.dll, и, как правило, у меня создалось впечатление, что COM и IIS не смешивались ужасно хорошо. This post рассказывает об уничтожении вашего первоначального AppDomain и создании нового. Возможно, это не обязательно в IIS?

Есть ли способ для дочернего приложения AppDomain эффективно выполнять методы внутри объекта Request, породившего его, и если да, то что это такое?

ответ

2

Я думаю, что я нашел простой способ для ребенка AppDomain, чтобы изменить состояние в родительском AppDomain без использования WCF или mscoree.dll. Перечитывая первое сообщение выше, я вижу, что он упоминает это как возможность, но отвергает его по причинам, которые мне не ясны. Хитрость заключается в том, чтобы создать объект, полученный из MarshalByRefObject в родителе, получить ObjectHandle к нему, а затем передать, что ObjectHandle к ребенку AppDomain. Затем ребенок может развернуть дескриптор, чтобы получить прокси, и затем может вызвать методы, которые изменят состояние объекта в родительском. Вот пример кода:

class Program 
{ 
    public class ParentFacade : MarshalByRefObject 
    { 
     public List<string> Collection { get; set; } 
     public void AddElement(string el) 
     { 
      Collection.Add(el); 
     } 
    } 

    public class ChildFacade : MarshalByRefObject 
    { 
     public void AlterParentState(ObjectHandle handle) 
     { 
      var parent = handle.Unwrap() as ParentFacade; 
      parent.AddElement("Message from child"); 
     } 
    } 

    static void Main(string[] args) 
    { 
     var child = AppDomain.CreateDomain("child"); 
     var childFacadeType = typeof(ChildFacade); 
     var childProxy = child.CreateInstanceAndUnwrap(childFacadeType.Assembly.FullName, childFacadeType.FullName) as ChildFacade; 

     var parentColl = new List<string>(); 
     var facade = new ParentFacade(); 
     facade.Collection = parentColl; 
     var facadeHandle = new ObjectHandle(facade); 
     childProxy.AlterParentState(facadeHandle); 

     foreach (var item in parentColl) 
      Console.WriteLine(item); 
    } 
} 

Этот код показывает, что метод у ребенка был в состоянии изменить состояние объектов в родительском. Этот конкретный пример не очень полезен, но это очень важно при настройке изолированной программы и включении .dll в дочернюю сборку, которой вы не доверяете. Неверная сборка может вызывать методы в ChildFacade и, таким образом, изменять состояние родителя контролируемым и безопасным способом.