Get the entire assembly in C# - c#

I'm trying to eliminate a call from my API in which the end-user has to pass Assembly.GetExecutingAssembly() in their code, currently my code looks lke the following.
public static Dictionary<int, Packet> Packets { get; private set; }
public static void Init()
{
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.GetTypes())
{
if (type.BaseType == typeof(Packet))
{
...
}
}
}
However this only gets all of the classes that are available in the API.dll, and none of the classes from the project that's using the .dll are included,
However if I pass it as a paramter, like so:
public static void Init(Assembly assembly) {}
it loads everything just fine, is this intended behaviour, is there a way to do this all in the background without the end-user ever having to worry about the Assmebly call?
In a nutshell - I have a .dll file that people will be using in their projects, I want to get all of the classes from the project that's using the .dll, not all of the classes inside of the .dll

Is it as simple as Assembly.GetCallingAssembly?

Why are you limiting your clients to have to define their Packet classes in a single assembly? What if a client wants to implement different types of Packet classes in different assemblies? What if someone wants to do run time code generation and create a Packet class at runtime?
Your API shouldn't care where or how Packet classes are defined. It should just expose an interface that will allow clients to register new Packet types directly. That will give clients the maximum flexibility.
Now it would be appropriate to provider helper methods so that clients could register types from assemblies or from the calling assemblies.
Something like:
class PacketRegistration {
public void RegisterPacketType(Type packetType) {...}
public void RegisterPacketType<TPacket>() where TPacket:Packet {
RegisterPacket(typeof(TPacket));
}
public void RegisterPacketTypesFromAssembly(Assembly assembly) {...}
public void RegisterPacketTypesFromCurrentAssembly() {
RegisterPacketTypesFromAssembly(Assembly.GetCallingAssembly());
}

Related

Injecting Internal Classes into Azure WebJob Functions

Is there any way for the default Functions class that comes in WebJob projects to be internal? We are using a job activator to inject via Unity some dependencies that are internal, which requires that the Functions class also be internal. When running the web job, we are seeing the following error:
No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).
When we make all the dependencies public, it works fine, so I know there's nothing wrong with my triggers or my job host config.
Here's my Program class:
class Program
{
static void Main()
{
var config = new JobHostConfiguration
{
JobActivator = new Activator(new UnityContainer())
};
config.UseServiceBus();
var host = new JobHost(config);
host.RunAndBlock();
}
}
Here's a simplified version of my Functions class:
internal class Functions
{
private readonly IMyInternalDependency _dependency;
public Functions(IMyInternalDependency dependency)
{
_dependency = dependency;
}
public function DoSomething([ServiceBusTrigger("my-queue")] BrokeredMessage message)
{
// Do something with the message
}
}
You must make the Functions class public. That appears to be just how Azure WebJobs works. You don't need to expose your concrete internal classes publicly. Just the interfaces:
public interface IDoStuffPublically
{
void DoSomething();
}
interface IDoStuffInternally
{
void DoSomething();
void DoSomethingInternally();
}
class DoStuff : IDoStuffPublically, IDoStuffInternally
{
public void DoSomething()
{
// ...
}
public void DoSomethingInternally()
{
// ...
}
}
And then your Functions class:
public class Functions
{
public Functions(IDoStuffPublically stuff)
{
_stuff = stuff;
}
private IDoStuffPublically _stuff;
// ...
}
And Unity will do something like this:
var job = new Functions(new DoStuff());
Dave commented:
It's frustrating that I cannot simply set the internals visible to the WebJob SDK...
You might be able to accomplish this... miiiiiiiiiight be able to...
There is a way for an assembly or executable to grant another assembly the permission to access internal members. I've done this before on a class library to allow my unit tests to call internal methods on a class as part of setting up a unit test.
If you know which assembly in Azure WebJobs actually creates the instance of your Functions class, and the assembly that invokes the methods on that class, you could white list those assemblies.
Crack open AssemblyInfo.cs and add one or more lines:
[assembly: InternalsVisibleTo("Microsoft.Azure.Something.Something")]
Reference: InternalsVisibleToAttribute class
Related reading: .Net Tips – using InternalsVisibleTo attribute to help testing non-public methods
I'm not sure which assemblies you would need to add, though.
When using Triggers with the Webjob SDK, you never register the functions to be executed.
When the jobhost starts (new JobHost(config).RunAndBlock()), it discoverers the functions to be executed based on parameter attributes.
Let's have a look at your code:
var config = new JobHostConfiguration
{
JobActivator = new Activator(new UnityContainer())
};
config.UseServiceBus();
Because you specify that you want to use servicebus, when the jobhost starts, it will discover and register (index) all the functions that have a parameter with the ServiceBusTrigger attribute.
I assume that the SDK uses something like MemberInfo.GetCustomAttributes to index the functions so don't know if it is (possible and) easy to get attributes from an internal class.

One DLL with two implementations for two applications

I have a DLL with some classes and methods. And two applications using it.
One admin-application that needs almost every method and a client-application that only needs parts of the stuff. But big parts of it are used by both of them. Now I want make a DLL with the admin stuff and one with the client stuff.
Duplicating the DLL and edit things manually everytime is horrible.
Maybe conditional compiling helps me but I dont know how to compile the DLL twice with different coditions in one solution with the three projects.
Is there a better approach for this issue than having two different DLLs and manually editing on every change?
In general, you probably don't want admin code exposed on the client side. Since it's a DLL, that code is just waiting to be exploited, because those methods are, by necessity, public. Not to mention decompiling a .NET DLL is trivial and may expose inner-workings of your admin program you really don't want a non-administrator to see.
The best, though not necessarily the "easiest" thing to do, if you want to minimize code duplication, is to have 3 DLLs:
A common library that contains ONLY functions that BOTH applications use
A library that ONLY the admin application will use (or else compile it straight into the application if nothing else uses those functions at all)
A library that ONLY the client application will use (with same caveat as above)
A project that consists of a server, client, and admin client should likely have 3-4 libraries:
Common library, used by all 3
Client library, used by client and server
Admin library, used by server and admin client
Server library, used only by server (or else compile the methods directly into the application)
Have you considered using dependency injection on the common library, some form of constructor injection to determine the rules that need to be applied during execution.
Here's a very simple example:
public interface IWorkerRule
{
string FormatText(string input);
}
internal class AdminRules : IWorkerRule
{
public string FormatText(string input)
{
return input.Replace("!", "?");
}
}
internal class UserRules : IWorkerRule
{
public string FormatText(string input)
{
return input.Replace("!", ".");
}
}
public class Worker
{
private IWorkerRule Rule { get; set; }
public Worker(IWorkerRule rule)
{
Rule = rule;
}
public string FormatText(string text)
{
//generic shared formatting applied to any consumer
text = text.Replace("#", "*");
//here we apply the injected logic
text = Rule.FormatText(text);
return text;
}
}
class Program
{
//injecting admin functions
static void Main()
{
const string sampleText = "This message is #Important# please do something about it!";
//inject the admin rules.
var worker = new Worker(new AdminRules());
Console.WriteLine(worker.FormatText(sampleText));
//inject the user rules
worker = new Worker(new UserRules());
Console.WriteLine(worker.FormatText(sampleText));
Console.ReadLine();
}
}
When run you'll produce this output.
This message is *Important* please do something about it?
This message is *Important* please do something about it.

Hosting CLR Runtime in C++

I am working on an extension for a project that will allow hosting the CLR inside the core application. With this I plan to allow this extension to manage managed extensions that it loads/unloads inside itself. That being said, I need to use separate AppDomains to ensure unloading is possible.
Currently, I am able to get the domains setup and get the plugin file loaded but at that point I'm stuck. I'm not sure how to call functions inside the domains loaded assembly at will and so on.
Here is my loading setup so far, minus error checking and such:
ICorRuntimeHost* lpRuntimeHost = NULL;
CorBindToRuntimeEx( L"v4.0.30319", L"wks", 0, CLSID_CorRuntimeHost, IID_PPV_ARGS( &lpRuntimeHost ) );
lpRuntimeHost->Start();
// File data read from disk.
// Dll file just CreateFile/ReadFile and insert into pluginFileData.
CComSafeArray<BYTE> pluginFileData;
IUnknown* lpUnknown = NULL;
lpRuntimeHost->CreateDomain( wstrPlugin.c_str(), NULL, &lpUnknown );
CComPtr<_AppDomain> appDomain = NULL;
lpUnknown->QueryInterface( &appDomain.p );
CComPtr<_Assembly> appAssembly = NULL;
hResult = appDomain->Load_3( pluginFileData, &appAssembly );
I have a class library that all plugins must reference and use in order to be considered a plugin. Which so far is nothing more than a base class to inherit:
namespace FrameworkAPI
{
public class IFrameworkPlugin
{
public override bool Initialize(IntPtr interfaceObj)
{
return false;
}
}
}
And then an extension would reference that class library and use that as its base:
namespace ClassLibrary1
{
public class Main : IFrameworkPlugin
{
public override bool Initialize(IntPtr interfaceObj)
{
// Return true to stay loaded.
return true;
}
}
}
What I am stuck at is how to do a few things:
How can I obtain the main class but as the base to invoke methods in the base that allow the main class to still handle?
How can I ensure that the main class inherits the base so I can ensure its a valid plugin file?
How I can freely invoke methods from the C++ side to fire events in the C# plugin.
For the firing events, the C++ plugin will call more things in the C# plugins once they are loaded, such as rendering events, command handling, etc.
Most of the examples I find online are specific to requiring the entire C# side to be static which I don't want. Also most do not use separate AppDomains and rather all execute in the default. I don't want this since it limits being able to unload a specific plugin.
If any other info is missing and needed feel free to let me know.
I resolved this issue by using a COM exposed interface for the C# side of things.
I have placed the FrameworkAPI inside a separate DLL and exposed it's main interface to COM then reference it in the plugins that will use it.
With it compiled with COM enabled, I can import the .tlb generated file to use the interface in C++ easily.

UnityContainer.RegisterType does not get used when put in a Static Constructor

This is an example console application (it will run fine after adding the Unity NugGet package) that seems to show a bug in Unity:
using System;
using Microsoft.Practices.Unity;
class GC { public static UnityContainer Container = new UnityContainer();}
class Program
{
static void Main(string[] args)
{
GC.Container.RegisterType<MyView>();
var myView = GC.Container.Resolve<MyView>();
Console.ReadLine();
}
}
public class MyClassDesign: MyClass{}
public class MyClass: VMBase<MyClass, MyClassDesign>{}
public abstract class VMBase<TViewModel, TDesignVM> where TDesignVM:TViewModel
{
static VMBase()
{
if (!GC.Container.IsRegistered(typeof(TViewModel)))
GC.Container.RegisterType(typeof (TViewModel), typeof(TDesignVM));
}
}
public class MyView
{
public MyView(MyClass myClass)
{
Console.WriteLine("Bad: "+myClass.GetType().ToString());
Console.WriteLine("Good: "+GC.Container.Resolve<MyClass>().GetType());
}
}
The output is:
Bad: MyClass
Good: MyClassDesign
The resolved type is MyClass. But it should be MyClassDesign. (The static constructor runs prior to MyClass being resolved in the MyView class.)
How can I get Unity to allow me to setup my Mapping in the Static Constructor?
Note: When I changed this setup the UnityContainer with a file (instead of in code) it all works fine. But I would rather not be dependent on an external file for this. (I am making a reusable template that I don't want to have too many dependencies in.)
Why do you want to put the registration logic inside your view model at all? This couples your application code to the container which is never a good idea. Have a look at the concept of Composition roots.
All setup code for the DI container should be placed there.
This isnt really a bug with Unity. The issue is that the static ctor is not run until an instance is requested (at which point unity still does not know about MyClassDesign). Which means that Unity has already started creating an instance of MyClass to fulfill the request. Any subsequent calls to GC.Container.Resolve<MyView>(); will result in the output you expect. As Sebastian Weber suggests, putting all your setup code in a completely seperate location (so your classes are not dependent on a specific DI container) is the best option.

Logging part specific error messages for mef parts

What is a preferred approach for logging part specific errors with imported parts? E.G. if you have the following contract:
public interface IDoStuff
{
void DoYourStuff();
}
with multiple implementations:
[Export(typeof(IDoStuff))]
public class DoStuffCorrectly : IDoStuff
{
//implement void run
}
[Export(typeof(IDOstuff))]
public class DoStuffWithExceptions : IDoStuff
{
// implement void run and throws exception
}
and you have a Type that uses mef to compose the parts.
public class DoStuffRunner
{
[ImportMany(typeof(IDoStuff))]
IEnumerable<IDoStuff> DoStuffPats {get;set;}
//some method that loops through the IEnumerable and calls run
public void Run()
{
foreach(IDostuff doit in DoStuffParts)
{
doit.Run();
}
}
}
In the executing assembly with the importer I am using entlib Exception Handling and Logging Application blocks. The logging application block is configured to send general error messages to the team. Some of the information that I would like to be able to include is which part failed, and possibly which group gets the email.
This is simple enough to configure statically in the app config, but would lead to a 1:1 configuration for each part that is added and kind defeats the purpose of dropping the dll in the bin. It would be neat if you could control the configuration in the part's assembly.
So, what are some possible approaches that would allow a part to expose information that could allow an imported part to provide logging configuration information that would jive with the MEF ideology?
The MEF way is to import a logging interface into your plugins and/or export whatever metadata you need to configure your logger by using custom attributes on your exported class.
I'm not really familiar enough with that logging library (we use log4net) to know what metadata you need or how logging would be actuated in a unified manner if you didn't import a logging interface interface.

Categories

Resources