简体   繁体   English

将参数传递给 WCF 构造函数

[英]Passing Parameters to WCF constructor

I have a WCF service in c#, that I would like to pass in some parameters upon initialization.我在 c# 中有一个 WCF 服务,我想在初始化时传入一些参数。 Now the error I get is service must be parameter less.现在我得到的错误是服务必须少参数。

I have read some articles online regarding dependency injection etc. But i'm not sure if that's what i want and have tried a few things and can't seem to get it to work.我已经在网上阅读了一些关于依赖注入等的文章。但我不确定这是否是我想要的,并且尝试了一些东西,但似乎无法让它工作。

I'm also calling it from x++ ax 2012. using ref=AifUtil::createServiceClient(clientType);我也从 x++ ax 2012 调用它。使用ref=AifUtil::createServiceClient(clientType); to create my service reference, but would like to pass in some parameters upon initial construction of the object.创建我的服务参考,但想在 object 的初始构建时传递一些参数。 Any simple ideas how to do this?任何简单的想法如何做到这一点?

You can't use parameterised constructors directly because of WCF default behaviours.由于 WCF 默认行为,您不能直接使用参数化构造函数。 However it is possible to do that with using implementaton of ServiceHostFactory , ServiceHost and IInstanceProvider .但是,可以使用ServiceHostFactoryServiceHostIInstanceProvider的实现来做到这一点。

Look at this: How do I pass values to the constructor on my wcf service?看看这个: 如何将值传递给我的 wcf 服务的构造函数?


EDIT: Added example codes from the link:编辑:从链接添加示例代码:

Given a service with this constructor signature:给定具有此构造函数签名的服务:

public MyService(IDependency dep)

Here's an example that can spin up MyService:这是一个可以启动 MyService 的示例:

public class MyServiceHostFactory : ServiceHostFactory
{
    private readonly IDependency dep;

    public MyServiceHostFactory()
    {
        this.dep = new MyClass();
    }

    protected override ServiceHost CreateServiceHost(Type serviceType,
        Uri[] baseAddresses)
    {
        return new MyServiceHost(this.dep, serviceType, baseAddresses);
    }
}

public class MyServiceHost : ServiceHost
{
    public MyServiceHost(IDependency dep, Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
        if (dep == null)
        {
            throw new ArgumentNullException("dep");
        }

        foreach (var cd in this.ImplementedContracts.Values)
        {
            cd.Behaviors.Add(new MyInstanceProvider(dep));
        }
    }
}

public class MyInstanceProvider : IInstanceProvider, IContractBehavior
{
    private readonly IDependency dep;

    public MyInstanceProvider(IDependency dep)
    {
        if (dep == null)
        {
            throw new ArgumentNullException("dep");
        }

        this.dep = dep;
    }

    #region IInstanceProvider Members

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        return this.GetInstance(instanceContext);
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return new MyService(this.dep);
    }

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

    #endregion

    #region IContractBehavior Members

    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.InstanceProvider = this;
    }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
    }

    #endregion
}

Register MyServiceHostFactory in your MyService.svc file, or use MyServiceHost directly in code for self-hosting scenarios.在您的 MyService.svc 文件中注册 MyServiceHostFactory,或直接在代码中使用 MyServiceHost 进行自托管方案。

For self-hosted WCF services such as the console, we can initialize the passed parameters directly in the service host life cycle event, or perform specific actions before the service starts.对于控制台等自托管的WCF服务,我们可以直接在服务宿主生命周期事件中初始化传入的参数,也可以在服务启动前执行特定动作。
For the WCF service is hosted in WCF, this feature could be completed by the service host factory property.对于 WCF 服务托管在 WCF 中,此功能可以由服务主机工厂属性完成。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/extending/extending-hosting-using-servicehostfactory https://docs.microsoft.com/en-us/dotnet/framework/wcf/extending/extending-hosting-using-servicehostfactory
https://blogs.msdn.microsoft.com/carlosfigueira/2011/06/13/wcf-extensibility-servicehostfactory/ https://blogs.msdn.microsoft.com/carlosfigueira/2011/06/13/wcf-extensibility-servicehostfactory/
Here is a detailed example related to authenticating the client with Asp.net membership provider, before the service running, we seed some data in the database.这是一个与使用 Asp.net 成员身份提供商验证客户端相关的详细示例,在服务运行之前,我们在数据库中播种了一些数据。
Svc markup. Svc 标记。

<%@ ServiceHost Language="C#" Debug="true" Factory="WcfService2.CalculatorServiceHostFactory" Service="WcfService2.Service1" CodeBehind="Service1.svc.cs" %>

Factory.工厂。

public class CalculatorServiceHostFactory : ServiceHostFactoryBase
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        return new CalculatorServiceHost(baseAddresses);
    }
}

class CalculatorServiceHost : ServiceHost
{
    #region CalculatorServiceHost Constructor
    /// <summary>
    /// Constructs a CalculatorServiceHost. Calls into SetupUsersAndroles to 
    /// set up the user and roles that the CalculatorService allows
    /// </summary>
    public CalculatorServiceHost(params Uri[] addresses)
        : base(typeof(Service1), addresses)
    {
        SetupUsersAndRoles();
    }
    #endregion

    /// <summary>
    /// Sets up the user and roles that the CalculatorService allows
    /// </summary>
    internal static void SetupUsersAndRoles()
    {
        // Create some arrays for membership and role data
        string[] users = { "Alice", "Bob", "Charlie" };
        string[] emails = { "alice@example.org", "bob@example.org", "charlie@example.org" };
        string[] passwords = { "ecilA-123", "treboR-456", "eilrahC-789" };
        string[] roles = { "Super Users", "Registered Users", "Users" };

        // Clear out existing user information and add fresh user information
        for (int i = 0; i < emails.Length; i++)
        {
            if (Membership.GetUserNameByEmail(emails[i]) != null)
                Membership.DeleteUser(users[i], true);

            Membership.CreateUser(users[i], passwords[i], emails[i]);
        }

        // Clear out existing role information and add fresh role information
        // This puts Alice, Bob and Charlie in the Users Role, Alice and Bob 
        // in the Registered Users Role and just Alice in the Super Users Role.
        for (int i = 0; i < roles.Length; i++)
        {
            if (Roles.RoleExists(roles[i]))
            {
                foreach (string u in Roles.GetUsersInRole(roles[i]))
                    Roles.RemoveUserFromRole(u, roles[i]);

                Roles.DeleteRole(roles[i]);
            }

            Roles.CreateRole(roles[i]);

            string[] userstoadd = new string[i + 1];

            for (int j = 0; j < userstoadd.Length; j++)
                userstoadd[j] = users[j];

            Roles.AddUsersToRole(userstoadd, roles[i]);
        }
    }
}

Official sample.官方样品。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-aspnet-membership-provider https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-aspnet-membership-provider
Feel free to let me know if there is anything I can help with.如果有什么我可以帮忙的,请随时告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM