Can I only make some methods visible to the end user when I'm publishing a DLL to third party applications?
My code is built upon 7-8 different projects which call each other, they have different namespaces like "Company.ProjectName" which I think relate under the "Company" namespace, and I only want one of the projects (which has an interface defined BTW) to be visible to outer world.
Every project in the solution compiles into DLL's and then I'm combining them using ILASM.
BTW, there are other projects using these in the solution that are not related to this dll.
Edit: will the internal keyword work even if the namespaces are constructed like "CompanyName.Project1", "CompanyName.Project2" ? Will they see each other?
You don't need to combine them, you just need a friend assembly:
When you are developing a class library and additions to the library are contained in separate assemblies but require access to members in existing assemblies that are marked as Friend (Visual Basic) or internal (C#).
...
Only assemblies that you explicitly specify as friends can access Friend (Visual Basic) or internal (C#) types and members.
The InternalsVisibleTo attribute:
[assembly: InternalsVisibleTo("AssemblyB")]
helps to lock it down so only the specified assembly can access the internal items.
(In answer to your edit: this is specified at the assembly level, it doesn't matter what the namespace is).
Use internal
See the example below
public class MyPublicClass
{
public void DoSomething()
{
var myInternalClass = new MyInternalClass();
myInternalClass.DoSomething();
}
}
internal class MyInternalClass
{
public void DoSomething()
{
}
}
In your DLL, MyPublicClass will be visible to external users - those who reference your DLL.
MyInternalClass will not be visible.
Related
I have to build three different editions of a DLL which contain API calls of our software. I have so far figured out the following way of doing it using inheritance. Can someone please confirm if I'm using inheritance the correct way (or if you have a suggestion for doing it a proper/better way?) I am new to this so still learning C# project programming.
So far I have main class of API_calls (which are common for all DLL editions) as follows:
namespace APIcalls
{
public partial class API_Calls
{
public void Common_function1()
{
}
public void Common_function2()
{
}
}
}
Then I have three .cs class files with something like the following in each of them (Edition_A, Edition_B, and Edition_C are the differing factors for each edition of DLL), any additional calls are included in partial class API_Calls as follows:
namespace dll_edition
{
public class Edition_A
{
public Edition_A()
{
// Code here for checking if current DLL is authorized
// Otherwise throw an exception
}
}
}
namespace APIcalls
{
public partial class API_Calls : Edition_A
{
public void Additional_Edition_A_function1()
{
}
public void Additional_Edition_A_function2()
{
}
}
}
In each assembly build I include Edition_A file, or Edition_B file, or Edition_C file and then I build all three assemblies which gives me three DLLs.
My question: Is this the proper way of doing it? Is there any negative about how I have done it? Or is there a better way of doing this? My ultimate goal is to have three editions of DLL with some common API calls in them and then various API calls specific to each DLL type.
Thank you for any input that you may have!
-DD
From what I understand, you have set of common functions in a common base class that is to be used by different other classes.
There are various ways of doing it with their own pros and cons:-
1) Creating seperate libraries for each type which you are doing, in which only limited functionality goes to end user and size of dll is small.This is better suited if you have dlls working on plus and play model where you just dump the dll in the bin amd new functiinality is in place.
This also makes your changes centric, so you know where your changes are. But what if you have distributed you dll to end clients and they need method in other dll, you again have to republish your changes.
2) Doing it all in 1 dll, unwanted functionality is exposed to client, deployment package could be heavy. But you have all the functionality readily available.
To summarize would mainly depend on your business and deployment model.
Personally I am a bigger fan of doing it all in one DLL and using a Factory Pattern to determine which version gets run at runtime, but if it must be 3 based on your requirements here is what I recommend.
Create 4 DLLs.
The first project will just contain the edition interface (e.g. The structure of the DLL, but no content on how it will work). This interface can be attached to the classes for the different versions of the DLL. Using this structure will set up the calling code so that it can use dependency injections for different editions of the DLL.
The other 3 DLLs will be the different editions of the DLL that you are required to build.
I want to know that how design application , actually applications like Firefox or Chrome that you can download add-on for them and use ??!!
How do it in .Net ???
How to allow others to make Add-Ons for your app?
1>You create a DLL which has an interface.This interface defines a set of methods,properties,events you want others to define and implement.
the plugin developer need to define this interface.This DLL is required by your app and the plugin developer..
2>The plugin developer would use that shared DLL and implement the interface by defining the methods or properties in it.
3>Your app would now load that plugin and cast it to the shared DLL's interface and then call the desired methods,properties i.e anything that was defined in the interface..
How would your App fetch plugins?
You create a folder where you would search for the plugins.This is the folder where others plugins would be installed or placed.
Example
This is your shared dll
//this is the shared plugin
namespace Shared
{
interface IWrite
{
void write();
}
}
The plugin devloper
//this is how plugin developer would implement the interface
using Shared;//<-----the shared dll is included
namespace PlugInApp
{
public class plugInClass : IWrite //its interface implemented
{
public void write()
{
Console.Write("High from plugInClass");
}
}
}
this is your program
using Shared;//the shared plugin is required for the cast
class Program
{
static void Main(string[] args)
{
//this is how you search in the folder
foreach (string s in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*PlugIn.dll"))//getting plugins in base directory ending with PlugIn.dll
{
Assembly aWrite = Assembly.LoadFrom(s);
//this is how you cast the plugin with the shared dll's interface
Type tWrite = aWrite.GetType("PlugInApp.plugInClass");
IWrite click = (IWrite)Activator.CreateInstance(tWrite);//you create the object
click.write();//you call the method
}
}
}
You should use Managed Extensibility Framework (MEF).
http://mef.codeplex.com/
http://msdn.microsoft.com/en-us/library/dd460648.aspx
Use MEF.
The Managed Extensibility Framework (MEF) is a new library in .NET
that enables greater reuse of applications and components. Using MEF,
.NET applications can make the shift from being statically compiled to
dynamically composed. If you are building extensible applications,
extensible frameworks and application extensions, then MEF is for you.
useful link for MEF.
http://mef.codeplex.com/
http://www.codeproject.com/Articles/376033/From-Zero-to-Proficient-with-MEF
http://www.codeproject.com/Articles/232868/MEF-Features-with-Examples
I'm using a 3rd party library which requires a static method to be invoked before it is used - it sets the serial key to validate the license for the software. I'm needing to use this library in multiple projects and I want to shield those projects from needing to worry about this license. Ideally, I'd like to create a shared assembly which will handle the licensing and reference it by the projects which use the library - and isolate those projects from even knowing that any licensing is taking place.
One way to start thinking about accomplishing this is to perhaps use an assembly attribute. So, I make one which has a contructor to set the license:
[AttributeUsage(AttributeTargets.Assembly)]
public class LibraryLicenseAttribute : Attribute
{
public LibraryLicenseAttribute()
{
Lib.SetLicense("valid key");
}
}
and place it in a wrapper project:
LibraryWrapperProject
Properties
AssemblyInfo.cs
References
Lib.dll
LibraryLicenseAttribute.cs
And have it invoked by including it in AssemblyInfo.cs:
[LibraryLicense]
Now, I can reference this project in another project which uses the library:
LibraryUserProject
References
LibraryWrapperProject
LibraryUser.cs
... but when I go to use the library ...
class LibraryUser
{
public LibraryUser()
{
Lib.Use();
}
}
It reports that the license hasn't been set. I've found that I can include the attribute in the calling project's AssemblyInfo.cs and the attribute will get invoked. This is better than redistributing the licensing to all the downstream projects, but they still need that extra cruft to make it work.
Furthermore - some of the projects are dynamically loaded elseware. For instance:
Assembly.Load("LibraryUserProject.dll");
How can I invoke the licensing assembly attribute when dynamically loading the assembly it is contained in? Is there another .NET framework feature that might make this easier?
Without much analysing your solution to the problem, i suggest you to check out the AppDomain.CurrentDomain.AssemblyLoad and AppDomain.AssemblyResolve events for running your code when the assembly resolved or loadded.
Another and more elegant solution may be using a static type initializers (static constructor) or Module Initializers. Static type intitializers are called the first time the type is referenced and easy to implement. However, Module Initializers in C# is not a trivial task but you can achive your goal by implementing.
I'm writing a class-library (IE BHO) in C# and currently wrangling with the large volume of what I think is junk output coming from REGASM's generated registry keys.
The short version is this: I only want to expose a handful of classes (currently: ONE class) to IE (and the rest of COM). Only one class has the ClassInterfaceAttribute and GUID stuff set, and I can test that the add-on only requires the COM registry keys for this class -- and yet, REGASM generates GUIDs and registry keys for every class in the entire project.
This is annoying and somewhat disturbing as I do not want my class names sitting in users' registry unless they absolutely have to be there.
To be fair, many of those other classes are marked public because I use them in a driver app from another project in the same solution, to work around IE's debugging black hole...
I'm still very green to COM in general (especially relating to .Net) and I was wondering what is the best way to hide all my other classes from regasm? Or, at least, why these classes that -- even though they are marked public -- are showing up when I haven't set any of the COM flags for them?
Thanks!
Use internal access modifier for stuff that doesn't need to have public modifier. For stuff that really needs public access use ComVisible attribute to partially hide it.
For example:
[ComVisible(false)]
public class ClassToHide {
//whatever
};
public class ClassToExpose {
public void MethodToExpose() {}
[ComVisible(false)]
public void MethodToHide() {}
};
All public member functions and member variables of all public classes are COM-visible by default. So first think of making them internal and if you really need them public hide them from COM with ComVisible.
Try using the /regfile switch - this will output a reg file rather than directly writing all your class names to the registry.
When you have the .reg file you can remove any entries you dont want to be added to the target systems registry, and deploy only those values to the target machine. Depending on how you choose to deploy your software, this might be easier and you would not have to change the code for any of your types.
In fact if you dont have access to the sourcecode, this would be the only way to achieve this.
I wrote a COM component with the same problems.
I separated all the non-COM functions into a separate helper DLL. The COM DLL only contains the code that needs to be registered. Everything else is accessed through the helper DLL.
I found that an easy way to make sure that future code wouldn't accidentally be marked as public rather than internal and show up in the registry.
Set ComVisible attribute to false in AssemblyInfo file and set apply ComVisible for only the desired classes.
Hope I'm asking this correctly:
I have a project
Projects.Client
I have my class library ( infrastructure stuff I use all the time )
Library
Assuming these are both projects, how can I do this from a class in the "Projects.Client"
using Library;
public class xxx
{
public void DoSomething()
{
Library.SomeDll.DoSomething();
}
}
SomeDll.dll is referenced in the "Library" project. "Library" is a reference in end client project "Projects.Client"
I know I could simply add SomeDll to the "Projects.Client" project but there are a number of items and I use them all the time. I'd like to be able to include the "Library" and somehow be able to reference everything within it(including raw code and dll's). Is this possible?
please note: I'd prefer not to write explicit wrappers for all the methods and the dll is static so I can not seem to get away with doing this in the "Library" project:
public static class WrapSomeDll
{
public static extern SomeDll Dll();
}
Any inventive answers are appreciated, I might not even need dual references, wrappers e.t.c.
Sorry, that doesn't work. You need the reference to SomeDll in order to use its metadata in Project.Client. It's really as simple as that.
Keep in mind that references aren't just a matter of resolving symbols to addresses. This is a matter of pulling over the metadata (types) so that it can be used.
You just need to reference the project and add using clauses for the namespaces you want to use. There is no need to specify the name of the DLL