如何使用 MEF 在 WCF 中应用 PIAB?

发布于 2024-12-08 01:02:33 字数 102 浏览 1 评论 0 原文

我的服务层充当域模型层的外观,以编排对域对象的调用。我为 WCF 服务编写了一个客户实例提供程序,以利用 MEF 来创建实例。现在我需要应用 PIAB 进行审计和日志记录。我怎样才能做到呢?

I have my service layer serving as a facade over my domain model layer to orchestrate calls to domain objects. I wrote a custome instance provider for my WCF services to harness MEF for instance creation. Now I need to apply PIAB for auditing and logging. How could I do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

祁梦 2024-12-15 01:02:33

Jimmy Tonner 写了一篇关于混合 MEF 和 PIAB 的精彩博客(请访问 http://blogs.msdn.com/b/jimmytr/archive/2010/06/22/mixing-mef-and-piab.aspx)。它启发了我将 PIAB 应用到 MEFied WCF 服务的解决方案。
想法很简单:首先使用 MEF 管理所有服务组合。然后在自定义实例提供程序中,通过MEF容器找到服务实例后应用PolicyInjection.Wrap。以下是代码示例:

服务:

[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
}

Jimmy Tonner has written a nice blog about mixing MEF and PIAB (visit http://blogs.msdn.com/b/jimmytr/archive/2010/06/22/mixing-mef-and-piab.aspx). It inspired my solution to applying PIAB to a MEFied WCF service.
Idea is simple: use MEF to manage all your service composition first. Then in the custom instance provider, apply PolicyInjection.Wrap after locating the service instance by MEF container. Below is the code sample:

Service:

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

Custom instance provider:

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文