Hot File

Embed an Assembly as a Resource

View: 666    Dowload: 0   Comment: 0   Post by: hanhga  
Author: none   Category: Embedded Systems   Fields: Computers - Technology

0 point/1 review File has been tested

If your application uses another dependent assembly, you have to deploy this assembly also together with your application. In some cases however, you wish you could only deploy your application assembly – and nothing else. To achieve this, you could embed the dependent assembly as a resource into your application assembly. Unfortunately, this is not the whole story. You also need some other things, which I will describe in the following. As an example, I will use the embedding of log4net.dll. I assume you already have an application using log4net. If not, it is a good idea to first create the application with the complete functionality. Not before nearly the end, embed the dependent assembly.

Introduction

Embed the Resource

The start is quite intuitive: add a folder Resources to your project, add the log4net.dll to this folder, and change its build action to Embedded Resource.

Load the Assembly

The next step is to load the assembly from the resources. This must be done before the first use of the assembly.

First, you must determine the name of the resource:

Assembly assembly = Assembly.GetExecutingAssembly();
string assemblyName = assembly.FullName.Split(',')[0];
string resourceName = assemblyName + ".Resources.log4net.dll";

Now you can load the assembly:

Stream imageStream = assembly.GetManifestResourceStream(resourceName);
long bytestreamMaxLength = imageStream.Length;
byte[] buffer = new byte[bytestreamMaxLength];
imageStream.Read(buffer, 0, (int)bytestreamMaxLength);
log4NetAssembly = Assembly.Load(buffer);

Remove the Reference

Until now, you have gained nothing. Because log4net.dll is still referenced in your project, the .NET loader tries to load it together with your assembly. Unfortunately, the .NET loader does not know that you embedded the log4net.dll in your assembly. Therefore, it produces an error during the load of your assembly:

Could not load file or assembly ' ... ' or one of its dependencies. 
The system cannot find the file specified.

This happens before the code in your assembly starts. Therefore, you have no chance to change this behavior. The only chance is to remove the reference from your assembly.

Create a Proxy

As soon as you remove the reference, you will not be able to compile your application anymore (which solves the deployment problem, albeit in an unwished way). This is quite clear, because now the compiler does not know what to do with your log4net calls.

To make your application compilable again, you have to add your own log4net classes, which call the original log4net assembly via reflection. Fortunately, you have to implement only these classes and methods you use.

A good idea is to create a new folder called Log4NetProxy. To this folder, you can add your own implementation for every needed class.

A typical use of log4net looks like this:

ILog logger = LogManager.GetLogger(typeName);
logger.Info(message);

In your proxy, now you need implementations for:

  • ILog
  • LogManager
  • LogImpl (which is returned by LogManager.GetLogger() and implements ILog)

Additionally, you should use a utility class called Loader.

Loader

The loader class should have a static variable, which contains the loaded assembly (as described above). Additionally, it should contain a helper method to get a specific type from the assembly:

static class Loader
{
  private static readonly Assembly log4NetAssembly = LoadAssembly();

  static static Assembly LoadAssembly()
  {
    ...
    return Assembly.Load(buffer);
  }

  internal static Type GetType(string typeName)
  {
    Type type = null;
    if (log4NetAssembly != null)
    {
      type = log4NetAssembly.GetType(typeName);
      if (null == type)
        throw new ArgumentException("Unable to locate type");
    }
    return type;
  }
}

ILog

The interface is quite simple. Just add all members from the original interface, which you use. For the example above, the following code is enough:

interface ILog
{
  void Info(object message);
}

LogManager

From the LogManager’s methods, you also need only one method. It first gets the LogManager type from the loaded assembly, and then it invokes the method GetLogger via reflection. Finally, the returned object will be encapsulated in LogImpl. The last step is necessary, because otherwise the using client (your application) would have to use reflection itself. But you want to leave your code as less changed as possible.

Overall, you get the following code:

static class LogManager
{
  public static ILog GetLogger(string name)
  {
    ILog logger = null;
    Type logManager = Loader.GetType("log4net.LogManager");
    if (logManager != null)
    {
      MethodInfo method = logManager.GetMethod("GetLogger", 
                            new[] { name.GetType() });
      logger = new LogImpl(method.Invoke(null, new[] { name }));
    }
    return logger;
  }
}

LogImpl

LogImpl also uses reflection to call the original implementation. Because it has instance methods, the real instance is a parameter to the constructor:

class LogImpl : ILog
{
  private readonly object instance;

  internal LogImpl(object instance)
  {
    this.instance = instance;
  }

  public void Info(object message)
  {
    MethodInfo method = instance.GetType().GetMethod("Info", 
                          new[] { message.GetType() });
    method.Invoke(instance, new[] { message });
  }
}

Use the Proxy

The rest is quite easy: in every class, you have a compile error because of the missing log4net assembly, replace the statement:

using log4net;

with:

using Log4NetProxy;

Handle the AssemblyResolve Event

For the most scenarios, the so far outlined solution should work. However, sometimes assemblies are also referenced in another way. In the case of log4net, this is its configuration, which looks like:

<log4net>
  <appender name="MyAppender" type="log4net.Appender.ConsoleAppender">
    ...
  </appender>
  ...
</log4net>

The XML above will be parsed from inside of log4net. However, it will try to load the type log4net.Appender.ConsoleAppender from the assembly log4net. Because the .NET loader does not know anything about our own loading, it looks itself for the log4net assembly. Again, we get:

Could not load file or assembly 'log4net' or one of its dependencies. 
The system cannot find the file specified.

To prevent this, you can give the loader a hint by hooking the AssemblyResolve event:

AppDomain.CurrentDomain.AssemblyResolve +=
  delegate(object o, ResolveEventArgs args)
  {
    if (args.Name == "log4net")
      return log4NetAssembly;
    else
      return null;
  };

The best place for this piece of code is immediately after the successful loading of the assembly.

Embed an Assembly as a Resource

Embed an Assembly as a Resource Posted on 08-04-2014  If your application uses another dependent assembly, you have to deploy this assembly also together with your application. In some cases however, you wish you could only deploy your application assembly – and nothing else. To achieve this, you could embed the dependent assembly as a resource into your application assembly. Unfortunately, this is not the whole story. You also need some other things, which I will describe in the following. As an example, I will use the embedding of log4net.dll. I assume you already have an application using log4net. If not, it is a good idea to first create the application with the complete functionality. Not before nearly the end, embed the dependent assembly. 5/10 666

Comment:

To comment you must be logged in members.

Files with category

  • OpenTheme : An open source graphic user interface (GUI) toolkit

    View: 4274    Download: 2   Comment: 0   Author: none  

    OpenTheme : An open source graphic user interface (GUI) toolkit

    Category: Embedded Systems
    Fields: Other

    0.29/50 review
    OpenTheme is an XML based GUI toolkit with a set of foundation class and WYSIWYG editor. Although it's originally designed for full screen GUI, it is also good for Windowed user interface, with full localization support and arbitary...

  • Design State Machine Engine for embedded system development

    View: 3419    Download: 2   Comment: 0   Author: none  

    Design State Machine Engine for embedded system development

    Category: Embedded Systems
    Fields: none

    0/6 review
    Embedded systems are some special purpose computers that are used inside of devices. Embedded systems generally use micro controllers that contain many functions of a computer on a single device. Embedded systems have to tightly work together with...

  • The StateWizard VC++ Add-in and Engine with Source Code

    View: 3944    Download: 0   Comment: 0   Author: none  

    The StateWizard VC++ Add-in and Engine with Source Code

    Category: Embedded Systems
    Fields: none

    0/8 review
    In an environment where software systems are more and more complex, concurrent, and real-time oriented, the choice of modeling languages and tools becomes the success key for many projects. This article introduces a cross-platform state-oriented...

  • Template merging with NVelocity and ASP.NET

    View: 2966    Download: 0   Comment: 0   Author: none  

    Template merging with NVelocity and ASP.NET

    Category: Embedded Systems
    Fields: Other

    0/6 review
    If you have ever tried to implement a newsletter system or a service for communicating with website users, you have probably faced the requisite to send multiple email messages with a common template and some differences, like a personalized greeting...

  • Use PowerShell to Manage your Intel AMT Data

    View: 1935    Download: 0   Comment: 0   Author: none  

    Use PowerShell to Manage your Intel AMT Data

    Category: Embedded Systems
    Fields: Other

    0.45/10 review
    This article is in the Product Showcase section for our sponsors at CodeProject. These reviews are intended to provide you with information on products and services that we consider useful and of value to developers.

  • A C++ Embedded Web Server

    View: 3108    Download: 1   Comment: 0   Author: none  

    A C++ Embedded Web Server

    Category: Embedded Systems
    Fields: Other

    0.75/6 review
    Do you have a web page or two? Nothing fancy, perhaps, but a neat demonstration of what can be achieved with a handful of HTML tags? Do you have a sophisticated C++ Windows desktop application which now needs to be controlled and monitored remotely?...

  • Java/.NET Integration as Simple as Possible

    View: 1525    Download: 2   Comment: 0   Author: none  

    Java/.NET Integration as Simple as Possible

    Category: Embedded Systems
    Fields: Other

    0/3 review
    For a number of years, I have been developing software for integrating applications written in different platforms. And in my business, I face with interoperability issues: Java and C++, Java and COM, Java and .NET. To solve them, I have developed a...

  • Writing a 16-bit dummy kernel in C/C++

    View: 2722    Download: 3   Comment: 0   Author: none  

    Writing a 16-bit dummy kernel in C/C++

    Category: Embedded Systems
    Fields: Other

    0/11 review
    In my previous articles I was only briefing about on how to write a boot loader. That was fun and challenging. I enjoyed it a lot. But after learning how to write a boot-loader I wanted to write much better stuff like embedding more functionality...

 
Newsletter Email

File suggestion for you

File top downloads

logo codetitle
Codetitle.com - library source code to share, download the file to the community
Copyright © 2015. All rights reserved. codetitle.com Develope by Vinagon .Ltd