Управление текстовым текстом Linq to SQL в службе WCF с использованием DataContextFactory - PullRequest
1 голос
/ 11 марта 2011

Я использовал код DataContextFactory Рика Страла ( Linq to SQL DataContext Lifetime Management ) в слое данных, используемом приложением ASP.Net.Это прекрасно работает, потому что текущий текст данных хранится в коллекции HttpContext.Items.Я знаю, что повторно использую один и тот же текст данных для каждого веб-запроса.

Однако я не смог успешно использовать фабрику в службе WCF.В приложении, отличном от HttpContext, фабрика хранит текстовый текст данных в слоте данных потока.

Thread.AllocateNamedDataSlot(key)

Проблема заключается в том, что независимо от того, как я настроил ConcurrencyMode и InstanceContextMode в моей службе, потоки повторно используются каждый вызови тот же dataContext используется повторно.Я не хочу этогоЯ хочу, чтобы для каждого вызова метода службы существовал только один текстовый текст.Есть ли способ добиться этого с помощью фабрики?Я не могу найти какую-либо уникальную информацию о каждом клиентском вызове, чтобы использовать его в качестве идентификатора для моего текста данных, чтобы он не использовался другими запросами ... независимо от того, является ли это один и тот же клиент.

Я хочуиспользовать свой бизнес-уровень и не обращаться непосредственно к своему уровню данных, но я боюсь, что мне, возможно, придется диктовать свои собственные единицы работы и связи данных в моей службе WCF.Кому-нибудь повезло, используя какую-то фабрику для своих данных в сервисе WCF?Я надеялся, что у моей фабрики есть способ узнать, используется ли она службой WCF, а затем уникальным образом обработать сохранение текста данных

public static T GetScopedDataContext<T>()
{
    if (HttpContext.Current != null)
        return (T)GetWebRequestScopedDataContextInternal(typeof(T), typeof(T).ToString(), null);

    // What can I put here to handle WCF services differently?
    return (T)GetThreadScopedDataContextInternal(typeof(T), typeof(T).ToString(), null);
}

И что можно сделать здесь, чтобы добиться того, что яхотите?

static object GetThreadScopedDataContextInternal(Type type, string key, string ConnectionString)
{
    if (key == null)
        key = "__WRSCDC_" + Thread.CurrentContext.ContextID.ToString();

    LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(key);

    object context = null;

    if (threadData != null)
        context = Thread.GetData(threadData);

    if (context == null)
    {
        if (ConnectionString == null)
            context = Activator.CreateInstance(type);
        else
            context = Activator.CreateInstance(type, ConnectionString);

        if (context != null)
        {
            if (threadData == null)
                threadData = Thread.AllocateNamedDataSlot(key);

            Thread.SetData(threadData, context);
        }
    }
    return context;
}

1 Ответ

0 голосов
/ 29 апреля 2011

У меня такая же проблема.Я использую контейнер Castle.Windsor IOC + образ жизни "PerWebRequest", и он работает так же, как ваш завод под капотом.

Я все еще пытаюсь найти идеальное решение для своих нужд, но у меня естьпромежуточное решение, которое может помочь вам: заставить вашу службу WCF работать с HttpContext :

1) В вашем проекте WCF попросите совместимость с ASP.Net

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>

2) Добавьте атрибут к вашему сервису для управления этой совместимостью

[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class MyService : IMyContract
{
  ...
}

Источник: Code rant

...