Как применить PIAB в WCF с MEF? - PullRequest
0 голосов
/ 04 октября 2011

У меня есть сервисный уровень, служащий фасадом над слоем моей модели домена, для организации вызовов к объектам домена.Я написал поставщика экземпляров обычного режима для своих служб WCF, чтобы использовать MEF для создания экземпляра.Теперь мне нужно применить PIAB для аудита и ведения журнала.Как я мог это сделать?

1 Ответ

0 голосов
/ 05 октября 2011

Джимми Тоннер написал хороший блог о смешении MEF и PIAB (посещение http://blogs.msdn.com/b/jimmytr/archive/2010/06/22/mixing-mef-and-piab.aspx).). Это вдохновило меня на решение применить PIAB к службе MEFied WCF. Идея проста: сначала используйте MEF, чтобы управлять всем составом услуг. Затем в поставщике пользовательского экземпляра примените PolicyInjection.Wrap после обнаружения экземпляра службы в контейнере MEF. Ниже приведен пример кода:

Услуги:

[Export(typeof(ICustomerService))]
public class CustomerService : ICustomerService
{
    #region ICustomerService Members
    public Customer GetCustomer(string customerID)
    {
        return CustomerDAO.GetCustomer(customerID);
    }
    #endregion
}

Поставщик пользовательского экземпляра:

public class PolicyInjectionInstanceProvider : IInstanceProvider
{
    private Type serviceContractType;

    private CompositionContainer Container { get; set; } 

    public PolicyInjectionInstanceProvider(Type t)
    {

        if (t!= null && !t.IsInterface)
        {
            throw new ArgumentException("Specified Type must be an interface");
        }

        this.serviceContractType = t;

    }

    #region IInstanceProvider Members

    public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
    {
        Type type = instanceContext.Host.Description.ServiceType;

        if (serviceContractType != null)
        {
            Compose();
            var importDefinition = new ImportDefinition(i => i.ContractName.Equals(serviceContractType.FullName), serviceContractType.FullName, ImportCardinality.ZeroOrMore, false, false);
            var atomicComposition = new AtomicComposition();
            IEnumerable<Export> extensions;

            Container.TryGetExports(importDefinition, atomicComposition, out extensions);

            if (extensions != null && extensions.Count() > 0)
            {
                var service = extensions.First().Value;
                return PolicyInjection.Wrap(serviceContractType, service);
            }                
        }
        else
        {
            if (!type.IsMarshalByRef)
            {
                throw new ArgumentException("Type Must inherit MarshalByRefObject if no ServiceInterface is Specified");
            }
            return PolicyInjection.Create(type);
        }
        return null;
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return GetInstance(instanceContext, null);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        var disposable = instance as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
        Container.Dispose();
    }

    #endregion

    #region Private Methods

    private void Compose()
    {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new DirectoryCatalog(@".\")); //Extensions
        Container = new CompositionContainer(catalog);
    }

    #endregion
}
...