سؤال

تشغيل ServiceHost بعقد واحد يعمل بشكل جيد على النحو التالي:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.Open();

الآن أود إضافة عقد ثانٍ (الثالث، الرابع، ...).سيكون تخميني الأول هو إضافة المزيد من نقاط النهاية مثل هذا:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();

لكن هذا لا يعمل بالطبع، لأنه عند إنشاء ServiceHost يمكنني إما تمرير MyService1 كمعلمة أو MyService2 - لذا يمكنني إضافة الكثير من نقاط النهاية إلى خدمتي، ولكن يجب على الجميع استخدام نفس العقد، حيث أنني فقط أستطيع توفير تنفيذ واحد؟
لدي شعور بأنني أفتقد النقطة هنا.بالتأكيد يجب أن تكون هناك طريقة ما لتوفير التنفيذ لكل عقد نقطة نهاية أقوم بإضافته، أم لا؟

هل كانت مفيدة؟

المحلول

وتحتاج إلى تنفيذ كل الخدمات (واجهات) في نفس الفئة.

servicehost = new ServiceHost(typeof(WcfEntryPoint));
servicehost.Open(); 

public class WcfEntryPoint : IMyService1, IMyService2
{
    #region IMyService1
    #endregion

    #region IMyService2
    #endregion
}

ومعلوماتك: أنا كثيرا ما تستخدم فئات جزئية لجعل بلدي رمز الفئة المضيف أسهل للقراءة:

// WcfEntryPoint.IMyService1.cs
public partial class WcfEntryPoint : IMyService1
{
    // IMyService1 methods
}

// WcfEntryPoint.IMyService2.cs
public partial class WcfEntryPoint : IMyService2
{
    // IMyService2 methods
}

نصائح أخرى

وأنا تواجه حاليا مع نفس المشكلة، ولقد قررت الذهاب مع تنفيذ أدناه. لست متأكدا ما إذا كانت هناك أي مشكلات في الأداء مع وجود هذا العدد الكبير من عقود الخدمة، ولكن في التنفيذ النهائي بلدي وأنا ربما يكون حوالي 10 - 15 عقود الخدمة، وبالتالي حوالي 10-15 ServiceHosts

وأنا استضافة جميع الخدمات WCF بلدي داخل خدمة ويندوز واحدة.

private void PublishWcfEndpoints()
{
    var mappings = new Dictionary<Type, Type>
    {
       {typeof (IAuthenticationService), typeof (AuthenticationService)},
       {typeof(IUserService), typeof(UserService)},
       {typeof(IClientService), typeof(ClientService)}
    };


    foreach (var type in mappings)
    {
        Type contractType = type.Key;
        Type implementationType = type.Value;

        ServiceHost serviceHost = new ServiceHost(implementationType);
        ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(contractType, ServiceHelper.GetDefaultBinding(),
                                                                  Properties.Settings.Default.ServiceUrl  + "/" + contractType.Name);
        endpoint.Behaviors.Add(new ServerSessionBehavior());

        ServiceDebugBehavior serviceDebugBehaviour =
            serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
        serviceDebugBehaviour.IncludeExceptionDetailInFaults = true;

        log.DebugFormat("Published Service endpoint: {0}", Properties.Settings.Default.ServiceUrl);

        serviceHost.Open();
        serviceHosts.Add(serviceHost);
    }

}

لا تتردد في التعليق على هذا النوع من إعداد، وإذا كان هناك أي مشاكل معها، خصوصا المتصلة بالأداء.

هذه الإجابة هي رد إضافي على التعليق في الإجابة المقبولة من chilltemp.

سام، يجب عليك حقًا تحديد سبب حاجتك إلى 10-50 عقدًا ومحاولة إيجاد حل آخر.لقد ألقيت نظرة على معايير ترميز WCF الخاصة بـ Juval Lowy (الموجودة في http://www.idesign.net/) ووجدت المراجع التالية:

3 عقود الخدمة...4.تجنب العقود مع عضو واحد.5.نسعى جاهدين للحصول على ثلاثة إلى خمسة أعضاء لكل عقد خدمة.6.ألا يزيد عدد الأعضاء عن عشرين عضوًا في عقد الخدمة الواحد.ربما يكون اثني عشر هو الحد العملي.

لم يذكر حدًا أقصى لتطبيقات العقود (التي يمكنني العثور عليها) ولكن لا يمكنني أن أتخيل أنه ينظر إلى 50 عقدًا على خدمة ما على أنها شيء يشبه أفضل الممارسات.أحد الحلول التي وجدتها تعمل بشكل جيد هو استخدام مشاركة الأعضاء لوظائف مماثلة.

على سبيل المثال، إذا كنت تستخدم خدمة WCF لإجراء العمليات الحسابية على قيمتين، فقد يكون لديك 4 أعضاء في جانب الخدمة:إضافة (x،y)، طرح (x،y)، ضرب (x،y)، قسمة (x،y).إذا قمت بدمجها في عضو أكثر عمومية واستخدمت كائنًا لتمرير البيانات المطلوبة، فيمكنك بسهولة تقليل عدد أعضائك وزيادة قابلية التوسع.مثال:PeformCalculation(obj) حيث يحتوي الكائن على خصائص x وy والإجراء (إضافة وطرح وضرب وقسمة).

أتمنى أن يساعدك هذا.

ولقد وجدت حلا آخر لهذه المشكلة عن طريق استخدام في RoutingService الصف. لا يزال يتعين استضافت كل عقد في انها ServiceHost الخاصة، ولكن يمكن أن يكون هناك RoutingService يجلس على رأس كل منهم - وتقديمها أكثر من "نقطة النهاية" موحدة. لقد كتبت أيضا codeproject المقالة حول هذا الموضوع. رمز المثال هو متاح أيضا على Bitbucket .

وسوف الجواب الفلفل الحار في العمل إذا كنت طيب مع عقود يجري تقاسمها من قبل الخدمة. إذا كنت تريد لهم أن ينفصل حاول هذا:

host1 = new ServiceHost(typeof(MyService1));
host2 = new ServiceHost(typeof(MyService2));

host1.Open();
host2.Open();

public class MyService1 : IMyService1
{
    #region IMyService1
    #endregion
}

public class MyService2 : IMyService2
{
    #region IMyService2
    #endregion
}

وتحرير: كما نشرت مات، فإن هذا يتطلب النهاية متعددة لكل خدمة / عقد

لا أحد enpoints موثقة. عرج استخدام أكثر من واحد (كمجموعة، من رابط مشترك، على سبيل المثال HTTP) يجب أن تستخدم مثلا ملزم نفسه (لا أكثر)، أي بمعنى.

وعينة الخاص بك:

servicehost = new ServiceHost(typeof(MyService1));
servicehost.AddServiceEndpoint(typeof(IMyService1), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), new NetTcpBinding(), "net.tcp://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();

يجب أن يكون واحد فقط جديد ملزم ()، اختبرت عبر HTTP.

servicehost = new ServiceHost(typeof(MyService1));
 BasicHttpBinding binding = new BasicHttpBinding();
servicehost.AddServiceEndpoint(typeof(IMyService1),binding , "http://127.0.0.1:800/MyApp/MyService1");
servicehost.AddServiceEndpoint(typeof(IMyService2), binding, "http://127.0.0.1:800/MyApp/MyService2");
servicehost.Open();

وأنا أتفق تماما مع الطبقة الجزئية تنفذ عدة عقود في بعض الملفات.

وماذا عن تقسيم هذا الامر مع العنوان الأساسي والخدمات المتعددة / عقود دون ذلك؟ أنا لست وراء developmachine الان ولكن شيئا من هذا القبيل:

HTTP: // MYSERVER / myservices / serviceA
HTTP: // MYSERVER / myservices / serviceB
HTTP: // MYSERVER / myservices / serviceC

وكل خدمة تنفذ ServiceContract الخاصة به.

ويمكنك تغيير
public class WcfEntryPoint : IMyService1, IMyService2
إلى
public partial class WcfEntryPoint : IMyService1
public partial class WcfEntryPoint : IMyService2

مثال

هل افتقد شيئا، أو هو أبسط حل غير مذكور هنا؟ أبسط حل هو هذا: لا تستخدم واجهات متعددة لخدمة الويب

ولكن هذا لا يعني أنك لا تزال والواجهات الخاصة بك فصل. هذا هو السبب لدينا الميراث واجهة.

[ServiceContract]
public interface IMetaSomeObjectService : ISomeObjectService1, ISomeObjectService2
{
}

واجهة ميتا يرث من كل الواجهات الأخرى.

[ServiceContract]
public interface ISomeOjectService1
{
    [OperationContract]
    List<SomeOject> GetSomeObjects();
}

[ServiceContract]
public interface ISomeOjectService2
{
    [OperationContract]
    void DoSomethingElse();
}

ثم الخدمة لديه واجهة ميتا فقط.

public class SomeObjectService : IMetaSomeObjectService
{
   public List<SomeOject> GetSomeObjects()
   {
       // code here
   }

   public void DoSomethingElse()
   {
       // code here
   }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top