Jarvis Bot
Jarvis Bot

Reputation: 491

How to share an object instance across assemblies in C#?

I have an assembly whose purpose is basic logging.

I have other assemblies that reference this assembly.

Is there a way to share an object instance across the referencing assemblies? So, that for one logging activity just one instance of the logging class is used?

For example, if the method inside Logger assembly/namespace is called AddInfo(). When Assembly A has a class that needs to log information it uses loggerInstance1.AddInfo() ... and when Assembly B needs to do the same...it re-uses the same loggerInstance1.AddInfo() ... and not loggerInstance2.AddInfo()

Upvotes: 3

Views: 4023

Answers (5)

dsum
dsum

Reputation: 1493

Are these two assembly running in the same app domain or same process? If you have total compilation control on both assembly, I would take FlipScript idea and create a singleton class, such that all logging is done though the same object.

Another option you can try is use a third party logging library. I used this one call log4net.

It is fairy simple to use and logging is highly configurable.

Upvotes: 0

Flipster
Flipster

Reputation: 4401

...and now for something completely different.

Another totally different strategy would be to reference system.web (yes, you can reference this assembly even in a desktop app):

using System.Web;

Then put any classes that you want to be "globally shared" into the Cache:

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

Finally, to get an instance of your global object, just pull it from the Cache:

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

BAM. Instant globally accessible, single-use objects, no Singleton pattern required.

Of course, you could also change the logic a bit to attempt to get the Logger, and if it does not already exist then create it for the first time and put it into the cache for future use. It just depends on if you know the order of access or not.

Upvotes: 6

TalentTuner
TalentTuner

Reputation: 17556

You can make use of any IoC conatiner if your project allows and register your class as Singleton Scope in the IoC than you can make use of container to get the single instance through out your assemblies.

But this solution requires the use of DI like Unity in .net

Upvotes: 2

Dan Turner
Dan Turner

Reputation: 2243

I half agree with Flip.

It does sounds like what you want in this specific case is to implement the Singleton pattern:

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

This is a perfectly valid OO design pattern, however its perhaps not the most testable solution to this problem. Due to the fact that its static it is potentially going to be more difficult to abstract when unit testing classes that depend on your logger.

An alternative solution would be to use an inversion of control container (such as Spring for java, or Spring.NET for MS.NET). With this approach, objects that depend on the logger simply expose a property of the type that is your logger. The IoC container recognises the type, and how to create one and will wire the dependency in for you. As part of registering your logger with the IoC container you can tell the container to treat the logger as a singleton, thus the same instance will be perpetually dished out.

This solution is obviously more convoluted, and for something like logging the singleton pattern may suit you better.

In fact I strongly suggest googling for some 3rd party libraries for logging. If you're using MS.NET, I have found log4net to be excellent.

Upvotes: 0

Flipster
Flipster

Reputation: 4401

Make the logging class a singleton in only one assembly, and as long as the singleton was written correctly and you create an instance of it through the public .GetInstance() method, you will only have a single instance created.

Something like this:

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; }
    }
}

I'm just curious: why is it such a big deal that another assembly create its own instance of your logging class? That would really be better OO, and probably more maintainable, especially if there is no concrete reason to prevent such behavior (and I can't think of a good reason for that in a logging class).

Upvotes: 3

Related Questions