So I have finally completed a project I have been working on for awhile, it's rather large and needs to be used in another project. With that I have decided I want to create a DLL out of the code (well a class library) ... plus I wanted to learn how to do it.

Well the problem is that it uses some References, specifically the System.Drawing one. When I import the DLL I have created into another project to test, it complains about missing the reference

The type 'System.Drawing.Bitmap' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

Well this just won't do, I want to make this DLL one big package where the user can import it and use it. So my question is, how do I include this reference in my Class Library project so that it's all nicely bundled up in one package?

Thanks

Recommended Answers

All 8 Replies

When I import the DLL I have created into another project to test, it complains about missing the reference

System.Drawing.Bitmap is a .NET standard class. The library assembly itself doesn't require you reference System.Drawing in the application that references your library, but if you expose the Bitmap class as a parameter or return value and require the application to recognize objects of it by type then the application does indeed need to reference System.Drawing because now that dependency is in the application.

You can eliminate that dependency by writing a wrapper around Bitmap within your library that only exposes features you'll be using. The application will use that class, and Bitmap will be hidden within it.

Here's a related example. I wanted to use the Aspose barcode recognition library in a DLL without forcing the application to reference or license that library. There was one type I couldn't expose: BarCodeReadType. What I did was create my own enumeration for the barcode type and my own Barcode class to hold the data:

/// <summary>
/// Represents supported barcode symbologies.
/// </summary>
[Flags]
public enum BarcodeType : long
{
    Codabar = BarCodeReadType.Codabar,
    Code11 = BarCodeReadType.Code11,
    Code128 = BarCodeReadType.Code128,
    Code39Standard = BarCodeReadType.Code39Standard,
    Code39Extended = BarCodeReadType.Code39Extended,
    Code93Standard = BarCodeReadType.Code93Standard,
    Code93Extended = BarCodeReadType.Code93Extended,
    Datamatrix = BarCodeReadType.DataMatrix,
    Ean13 = BarCodeReadType.EAN13,
    Ean8 = BarCodeReadType.EAN8,
    Patch = BarCodeReadType.PatchCode,
    Pdf417 = BarCodeReadType.Pdf417,
    Postnet = BarCodeReadType.Postnet,
    Qr = BarCodeReadType.QR,
    Upca = BarCodeReadType.UPCA,
    Upce = BarCodeReadType.UPCE
}

/// <summary>
/// Contains information for extracted barcodes.
/// </summary>
public class Barcode
{
    public int Page { get; private set; }

    /// <summary>
    /// Gets the barcode symbology.
    /// </summary>
    public BarcodeType Type { get; private set; }

    /// <summary>
    /// Gets the read direction.
    /// </summary>
    public double Angle { get; private set; }

    /// <summary>
    /// Gets the barcode value string.
    /// </summary>
    public string Value { get; private set; }

    /// <summary>
    /// Creates and initializes a new Barcode object.
    /// </summary>
    /// <param name="type">The type of the barcode.</param>
    /// <param name="angle">The read angle.</param>
    /// <param name="value">The data string.</param>
    public Barcode(BarcodeType type, double angle, string value, int page = 0)
    {
        Page = page;
        Type = type;
        Angle = angle;
        Value = value;
    }
}

Problem solved. The calling application can now reference just my library, then use the BarcodeType and Barcode types without even knowing that Aspose was used internally.

Sorry for the late reply, been busy

But I still definetly have to try this out, possibly tonight if I can and see if it does the trick.

Okay so as I look at this more, I am still a little confused. How exactly does this allow me to get around the issue of the reference?

Because a library only needs to link what it uses.

So if you have a library which uses another library....

Library 1:

namespace MyNamespace.People
{
    public class Person
    {
        String Name {get;set;}
        Int32 Age {get;set;}
    }
}

Library 2:

using MyNamespace.People;

namespace MyNamespace.DataModification
{
    public interface IPersonModifier
    {
        Boolean SetAge(String nameOfPerson, Int32 age);
    }

    public class PersonContainer : IPersonModifer
    {
        private List<Person> _personList = new List<Person>();

        public PersonContainer()
        {
            // Pretend it got a list of Person from somewhere
        }

        public Boolean SetAge(String name, Int32 age)
        {
            Person personToModify = _personList.SingleOrDefault(x => x.Name == name);
            if(personToModify != default(Person))
            {
                personToModify.Age = age;
                return true;
            }

            return false;
        }
    }
}

Library 3:

using MyNamespace.DataModification;

namespace MyNamespace.MainApplication
{
    private static IPersonModifier _container = new PersonContainer();

    public static void Main(String[] args)
    {
        // Pretend that there is a person called Bob
        _container.SetAge("Bob", 25);
    }
}

So in Library 3, we only have to reference Library 2. In Library 2 we must reference Library 1, but this means that Library 3 doesn't need to reference Library 1.

Until we use the Person object in Library 3, we do not need to reference Library 1, even though Library 2 uses it.

But doesn't this still need to reference to the dll in some way? That's what I am having trouble comprehending.

I can see what's going on, but what bugs me is we still need to access the reference in some way don't we? For instance in my case, the Bitmap

Not if you abstract away from it you don't. Only the library that uses it directly. Hang about for 15 minutes I'll write you up an example.

In Ketsu's example, Library 3 only needs to reference Library 2 and not Library 1. Library 2 references Library 1.

You have to reference what you use by name. If you don't use something by name because it's hidden in another library, you don't need to reference it.

Okay, I wrote a project for you to see. You will notice that the "TastyMeats" library includes a reference to System.Drawing.

The "InteropLibrary" includes a reference to "TastyMeats" but not to System.Drawing. I don't use anything from the System.Drawing namespace in that library.

The "AngelOfDarkness" library does include System.Drawing because I wanted to output an image and Winforms apps include it by default. However, I didn't have to I could have just output the list of bytes if I wanted to...

Anyway, here you go

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.