Введите тот же экземпляр DataContext через несколько типов с Единицей

Python 2

Вы можете использовать StringIO :

>>> msg = "Bob Smith\nJane Doe\nJane,\nPlease order more widgets\nThanks,\nBob\n"
>>> msg
'Bob Smith\nJane Doe\nJane,\nPlease order more widgets\nThanks,\nBob\n'
>>> import StringIO
>>> buf = StringIO.StringIO(msg)
>>> buf.readline()
'Bob Smith\n'
>>> buf.readline()
'Jane Doe\n'

Обязательно используйте cStringIO , если производительность важна.

Python 3

Вы можете использовать io.StringIO :

>>> import io
>>> buf = io.StringIO(msg)
>>> buf.readline()
'Bob Smith\n'
>>> buf.readline()
'Jane Doe\n'
>>> len(buf.read())
44
6
задан Sergejus 22 May 2009 в 19:34
поделиться

3 ответа

Если я правильно понимаю ваш вопрос (и если вы используете единство ... Я полагаю, что вы это делаете, потому что у вас есть пометил его с помощью единства) вы можете сделать что-то вроде этого:

В реализациях вашего репозитория,

[InjectionConstructor]
public SqlRepository(
    [Dependency] DataContext ctx)

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

Альтернативный подход - сделать что-то вроде этого с вашим репозиторием:

[InjectionMethod]
public void Initialize(
    [Dependency] DataContext ctx

это скажет unity вызвать этот метод, если вы в своем конструкторе службы,

0
ответ дан 10 December 2019 в 00:44
поделиться

Вы пробовали использовать метод RegisterInstance () для контейнера единства? Что-то вроде этого может сработать:

public static UnityContainer CreateContainer () { UnityContainer container = new UnityContainer ();

        try
        {
            var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;

            if (section != null)
            {
                section.Containers[0].Configure(container);
            }
        }
        catch (Exception ex)
        {
            TraceLogger.LogMessage("Configurarion Error for Unity Container", ex.Message, TraceEventType.Critical);
            Environment.Exit(1);
        }


        container.RegisterInstance(new DataContext());
        return container;
    }

Теперь каждый раз, когда этот контейнер пытается построить объект, которому требуется DataContext, будет передаваться тот же экземпляр. Вы даже можете настроить DataContext перед регистрацией его экземпляра.

ОБНОВЛЕНИЕ: Один из вариантов (сейчас я не знаю, действительно ли это хорошая практика, но это сработало для меня) - создать отдельный контейнер для каждого объекта, который вы собираетесь создать. Что-то вроде:

UnityContainer container1 = ContainerFactory.CreateContainer();
UnityContainer container2 = ContainerFactory.CreateContainer();
UnityContainer container3 = ContainerFactory.CreateContainer();
MyObject1 object1 = container1.Resolve<MyObject1>();
MyObject2 object2 = container2.Resolve<MyObject2>();
MyObject3 object3 = container3.Resolve<MyObject3>();

или более кратко:

MyObject1 object1 = ContainerFactory.CreateContainer().Resolve<MyObject1>();
MyObject1 object2 = ContainerFactory.CreateContainer().Resolve<MyObject2>();
MyObject1 object3 = ContainerFactory.CreateContainer().Resolve<MyObject3>();

Что ж, есть много способов сделать это, создав список, используя фабричный шаблон. Надеюсь, это поможет

0
ответ дан 10 December 2019 в 00:44
поделиться

Думаю, я знаю, что вы хотите сделать. Я нахожусь в той же лодке и пытаюсь найти решение.

Мой слой Service выполняет операции над входящими запросами, и то, что он делает, зависит от содержимого. Он передает его ряду классов с цепочкой ответственности. Я хочу, чтобы один и тот же контекст передавался всем классам в течение времени жизни метода службы под названием

Вы можете указать PerResolveLifetimeManager. Пока что, похоже, это работает с моими тестовыми примерами:

Класс сервиса:

public interface IServiceClass
{
    void DoService();
}

class ServiceClass : IServiceClass
{
    private IHandler Handler { get; set; }

    public ServiceClass(IHandler handler)
    {
        Handler = handler;
    }

    public void DoService()
    {
        Handler.HandleRequest();
    }
}

IHandler реализован двумя классами и выполняет паттерн Chain of Responsibility:

    public interface IHandler
{
    void HandleRequest();
}

class Handler : IHandler
{
    private IDataContext DataContext { get; set; }
    public Handler(IDataContext dataContext)
    {
        DataContext = dataContext;
    }

    public void HandleRequest()
    {
        DataContext.Save("From Handler 1");
    }
}

class Handler2 : IHandler
{
    private IDataContext DataContext { get; set; }
    private IHandler NextHandler { get; set; }

    public Handler2(IDataContext dataContext, IHandler handler)
    {
        DataContext = dataContext;
        NextHandler = handler;
    }

    public void HandleRequest()
    {
        if (NextHandler != null)
            NextHandler.HandleRequest();

        DataContext.Save("From Handler 2");
    }
}

Как вы можете видеть, оба обработчика принимают экземпляр IDataContext, который я хочу, чтобы был одинаковым в обоих. Handler2 также принимает экземпляр IHandler для передачи управления (здесь для демонстрации он принимает оба, но на самом деле только один будет обрабатывать запрос...)

IDataContext. В конструкторе я инициализирую Guid, а во время его работы вывожу его, чтобы я мог видеть, что оба раза, когда он вызывается, используется один и тот же экземпляр:

public interface IDataContext
{
    void Save(string fromHandler);
}

class DataContext : IDataContext
{
    private readonly Guid _guid;

    public DataContext()
    {
        _guid = Guid.NewGuid();
    }

    public void Save(string fromHandler)
    {
        Console.Out.WriteLine("GUI: [{0}] {1}", _guid, fromHandler);
    }
}

Наконец, регистрация и вызов сервиса:

    private IUnityContainer container;
    private void InitializeUnity()
    {
        container = new UnityContainer();
        container.RegisterType<IHandler, Handler2>("Handler2",
            new InjectionConstructor(new ResolvedParameter<IDataContext>(), new ResolvedParameter<IHandler>("Handler1")));
        container.RegisterType<IHandler, Handler>("Handler1");
        container.RegisterType<IDataContext, DataContext>(new PerResolveLifetimeManager());
        container.RegisterType<IServiceClass, ServiceClass>("MyClass", new InjectionConstructor(new ResolvedParameter<IHandler>("Handler2")));
    }

    private void CallService()
    {
        var service = container.Resolve<ServiceClass>("MyClass");
        service.DoService();

        // Resolving and calling again to simulate multiple resolves:
        service = container.Resolve<ServiceClass>("MyClass");
        service.DoService();
    }

Вот что я получаю:

GUI: [f2250055-8a5f-4f80-a1b6-bcc5574138cf] From Handler 1
GUI: [f2250055-8a5f-4f80-a1b6-bcc5574138cf] From Handler 2
GUI: [22a5c0a3-3c5c-4683-807d-bf2b43f3cd0a] From Handler 1
GUI: [22a5c0a3-3c5c-4683-807d-bf2b43f3cd0a] From Handler 2

Надеюсь, эта стена текста ответила на ваш вопрос... Если нет, извините, но он вдохновил меня на решение, которое мне нужно было реализовать...

3
ответ дан 10 December 2019 в 00:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: