Create WCF Data Service for use in service host

2019-06-25 16:43发布

问题:

I have a service application that host several WCF endpoints through different bindings. I want now to host a WCF Data Service in the same service Host. This post makes me believe it's possible. However, every single example on how to create a WCF Data Service creates it from inside an ASP.NET Web project, not a Class Library or Service Application. In fact, the WCF Data Service doesn't even show up in the Add New Item when selected from one of these project types.
My question is how do I create a WCF Data Service inside a Class Library, that will be called by a service host, that's already hosting several other WCF endpoints? The link I already referenced shows me how to host the Data Service after it's created, but since it doesn't show up as an option of the Add New Item, I'm kinna stuck.

回答1:

Yes, you can host a WCF Data Service in your own assembly - with a few little tricks.

Here's how:

  • put your data model (EF Data Model) into its own assembly, let's call it DataModel

  • create a new class library project (call it MyDataServiceHost)

  • add a few references:

    • your DataModel assembly with the data layer
    • System.ServiceModel
    • System.ServiceModel.Web
    • System.Data.Services.Client
    • System.Data.Services - you cannot pick this from the usual Add Reference dialog under the .NET category - you need to browse for the assembly file. Find the directory C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0 (or C:\Program Files (x86)\... on a 64-bit machine) and pick the System.Data.Services.dll inside it
  • add a new class to that class library and call it e.g. YourDataService.cs - it will look something like this:

    using System.Data.Services;
    using System.Data.Services.Common;
    
    using DataModel;
    
    namespace MyDataServiceHost
    {
        public class YourDataService : DataService<YourModelEntities>
        {
            // This method is called only once to initialize service-wide policies.
            public static void InitializeService(DataServiceConfiguration config)
            {
                // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
                // Examples:
                config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            }
        }
    }
    

    You can name the class anything you like, and it has to derive from DataService<T> where T is the name of your data model; if you're using Entity Framework, it's the name of your object context class - typically something like (database)Entities or whatever you picked when you created the EDM

  • add another class to your new project, call it MyDataServiceHost.cs and it will look something like this:

    using System;
    using System.Data.Services;
    
    using DataModel;
    
    namespace MyDataServiceHost
    {
        public class MyDataServiceHost
        {
            public static void LaunchDataService(string baseAddress)
            {
                Uri[] baseAddresses = new Uri[1];
                baseAddresses[0] = new Uri(baseAddress);
    
                using(DataServiceHost host = new DataServiceHost(typeof(YourDataService), baseAddresses))
                {
                    host.Open();
                    Console.WriteLine("DataService up and running.....");
    
                    Console.ReadLine();
                    host.Close();
                }
            }
        }
    }
    

    It instantiates a DataServiceHost, which is derived from WebServiceHost (which in turn is derived from ServiceHost) and it will spin up the WCF Data Service runtime for you.

  • now you can start up your WCF Data Service from any app using:

    MyDataServiceHost.LaunchDataService("http://localhost:4444/YourService");
    
  • last thing to remember: the app that you use to launch the WCF Data Service must have the connection string (the EDM connection string, if you're using Entity Framework) in its app.config (or web.config) in order for this to work!



回答2:

One way you may be able to accomplish this is to create an ASP.NET project to contain the WCF Data Service and then define a custom data service host (scroll down to the 'Defining a Custom Data Service Host' section) that acts as a mediator between your existing WCF host and the Data Service.



回答3:

After a lot of digging, I found the answer at this post: http://social.msdn.microsoft.com/Forums/en/adodotnetdataservices/thread/3191377e-f3f9-4d46-8daf-431cf74cef7c
I need to use the DataService<T> class, passing my ObjectContext that holds all my Entities. Worked perfectly