Как поделиться экземпляром объекта между сборками в C #? - PullRequest
1 голос
/ 24 декабря 2010

У меня есть сборка, основной целью которой является ведение журнала.

У меня есть другие сборки, которые ссылаются на эту сборку.

Есть ли способ поделиться экземпляром объекта между ссылочными сборками? Итак, что для одной операции регистрации используется только один экземпляр класса регистрации?

Например, если метод внутри сборки / пространства имен Logger называется AddInfo(). Когда сборка A имеет класс, который должен регистрировать информацию, она использует loggerInstance1.AddInfo() ... и когда сборка B должна делать то же самое ... она повторно использует тот же loggerInstance1.AddInfo() ... и не loggerInstance2.AddInfo()

Ответы [ 5 ]

4 голосов
/ 24 декабря 2010

... и теперь для чего-то совершенно другого.

Другая совершенно другая стратегия будет ссылаться на system.web (да, вы можете ссылаться на эту сборку даже в настольном приложении):

using System.Web;

Затем поместите все классы, которые вы хотите «глобально использовать», в Cache:

HttpRuntime.Cache.Insert("Logger", LoggingObject, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration);

Наконец, чтобы получить экземпляр вашего глобального объекта, просто извлеките его из Cache:

object LoggingObject = HttpRuntime.Cache.Get("Logger");

БАМ.Мгновенные глобально доступные, одноразовые объекты, шаблон Singleton не требуется.

Конечно, вы также можете немного изменить логику, чтобы попытаться получить Logger, и, если он еще не существует, создайте его дляпервый раз и положить его в кэш для дальнейшего использования.Это зависит только от того, знаете ли вы порядок доступа или нет.

3 голосов
/ 24 декабря 2010

Сделайте класс журналирования синглтоном только в одной сборке, и если синглтон был написан правильно и вы создаете его экземпляр с помощью общедоступного метода .GetInstance(), у вас будет создан только один экземпляр.

Примерно так:

class Singleton
{
    private static Singleton instance;
    private static int usageCount;

    private Singleton()
    {
        usageCount= 0;
    }
    public static Singleton GetInstance()
    {
        if (instance == null)
        {
            instance = new Singleton();
        }
        usageCount++;
        return instance;
    }
    public static int UsageCount
    {
        get { return usageCount; }
    }
}

Мне просто любопытно: почему это так важно, что другая сборка создает свой собственный экземпляр вашего класса журналирования? Это действительно было бы лучше ОО и, возможно, более легко обслуживаемо, особенно если нет конкретной причины, чтобы предотвратить такое поведение (и я не могу придумать вескую причину для этого в классе ведения журнала).

1 голос
/ 24 декабря 2010

Вы можете использовать любой соединитель IoC, если ваш проект разрешает, и зарегистрировать свой класс как Singleton Scope в IoC, чем вы можете использовать контейнер для получения единственного экземпляра через ваши сборки.решение требует использования DI, как Unity в .net

0 голосов
/ 24 декабря 2010

Работают ли эти две сборки в одном домене приложения или в одном процессе? Если у вас есть полный контроль над компиляцией в обеих сборках, я бы взял идею FlipScript и создал бы одноэлементный класс, чтобы все журналирование выполнялось через один и тот же объект.

Другой вариант, который вы можете попробовать - использовать стороннюю библиотеку журналов. Я использовал этот один вызов log4net .

Это очень просто в использовании, и регистрация очень настраивается.

0 голосов
/ 24 декабря 2010

Я наполовину согласен с Flip.

Похоже, что в данном конкретном случае вы хотите реализовать шаблон Singleton:

http://www.dofactory.com/Patterns/PatternSingleton.aspx#_self1

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

Альтернативным решением будет использование инверсии контейнера управления (например, Spring для Java или Spring.NET для MS.NET). При таком подходе объекты, зависящие от регистратора, просто предоставляют свойство типа, который является вашим регистратором. Контейнер IoC распознает тип и способ его создания и подключит зависимость для вас. Как часть регистрации вашего регистратора в контейнере IoC, вы можете указать контейнеру обрабатывать регистратор как одноэлементный, поэтому один и тот же экземпляр будет постоянно удален.

Это решение, очевидно, более запутанное, и для чего-то вроде регистрации одноэлементный шаблон может вам подойти лучше.

На самом деле я настоятельно рекомендую поискать в некоторых сторонних библиотеках для регистрации. Если вы используете MS.NET, я считаю, что log4net отлично работает.

...