I have a build engine which I am adding customisation to.
The customisation I am adding is in the form of a library which contains functions specific to Subversion.
My problem is, now I have separated this functionality into a main exe and several dll's, this dll requires a reference to some of the classes inside the main project (exe).
For example:
My Build Engine program contains a 'Project Class'.
The SVN dll has a function with signature:
SVNSourceControl(Project project, Logger logger)
I instantiate the SVN class with a reference to the Project I build as well as a Logger that carries out the logging for me.
The logger is fine as I have separated that into another dll and added references.
Do I need to separate my 'project' class into a separate dll and add references?
Do I need to add a reference to my dll which is the reference to my main exe and the classes within it?
Do I need to re-code the library to get round it some how? (Hopefully not :))
Thanks.
One thing you could do would be to create an interface for your Project class that exposes the parts of Project that you need access to in your library:
public interface IProject
{
string Name { get; }
}
Then change your SVNSourceControl() method to accept the interface instead of the class:
SVNSourceControl(IProject project, Logger logger)
Once that's done, all that's left is to define Project in your main exe as implementing IProject:
public class Project : myDllNamespace.IProject
{
public string Name { get; private set; }
// Whatever else
}
This is assuming that the dll containing the IProject interface and SVNSourceControl() method are already added as a reference to the main dll. If that's not true, you'll have to do that as well.
Related
I build a class library project with separate class by folder.
Example:
TEST
Security
Converter
Utility
After I compile project, I will have TEST.dll
but I want TEST.dll, TEST.Security.dll, TEST.Converter.dll, & TEST.Utility.dll
Note: Security, Converter, Utility is folder in TEST project. In each folder have c# class.
How to do?
Create separate projects for each
Example:
name project TEST.Security class library
name project TEST.Converter class library
name project TEST.Utility class library
the fact that you separate classes by folders means nothing when it comes to the dll output.
If you want one dll per folder then you will have to create one separate class library project for each one. In the properties of each project you can set the name of the dll file itself.
This being said, the name of the dll is less important, it's the namespaces that will matter. The namespace is set in each class file and this will affect your "using" statements.
I have 3 projects in my solution:
1- ExporterLib (Class Library)
2- ImporterApp (WPF Application)
3- SharedLib (Class Library)
the first two projects reference "SharedLib" which contains an interface called ISharedClass .
Inside "ImporterApp" I have a class called ClassA:
public class ClassA
{
[Import] private ISharedClass part;
}
Inside "ExporterLib" I have a class called SharedClassExport:
[Export(ISharedClass)]
public class SharedClassExport : ISharedClass
{
//....
}
In ImporterApp I use a DirectoryCatalog referencing ExporterLib.dll file and a container. But when I try to compose the parts of ClassA instance using the container I receive an exception saying:
1) No exports were found that match the constraint:
ContractName SharedLib.ISharedClass
RequiredTypeIdentity SharedLib.ISharedClass
When I use the debugger to see the parts inside the catalog I see the correct SharedClassExport Part, but it's not referencing ISharedClass!
What Should I Do?
P.S. : I want to use MEF and I don't want to merge any of these projects together.
Thanks in advance.
SUMMARY:
//Specifying the contract type may be important if
you want to export a type other then the base type,
such as an interface.
https://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=vs.110).aspx
Please try using [Export(typeof(ISharedClass))] . If you are exporting a type other than a base type, such as interface, it is important to specify the full contract type using typeof. To match the export use [Import(typeof(ISharedClass))]. Please let me know if this worked if not please provide the DirectoryCatalog composition logic you are using?
Check the bin folder of ImporterApp after your build. I'm willing to wager that ExporterLib.dll is not in the folder. Since ExporterLib.dll is not a direct dependency of ImporterApp MSBuild doesn't copy it to ImporterApp's bin folder on build. To fix this you have a few choices:
You can add a reference to ExporterLib in the ImporterApp project.
If you don't want to add the reference, a post build step on ImporterApp to copy the ExporterLib.dll to the bin directory of ImporterApp would also work.
You could also setup each project to build to the same directory in the solution structure.
I have created a store in nopcommerce and now I want to add my own plugin in that store.
For that,
I have created one class library project and in that I have created one class in which I have to implement IPlugin Interface which resides in another class of another class library project.
Now, I can't access that class in my solution.
So what should I do for implementing it in my class library?
First remember that class should be public,so you can access outside of the project
second ,build project
third,add reference to another project and .DLL file
I'm working on a C# class library project. This project references other DLL files, such as log4net.dll. In this project I have only one class that uses log4net.dll. When other project references my project, I want to copy log4net.dll to its bin folder only if the other project is calling the class that uses log4net.dll.
Is this feasible?
Split your library in two and remove the reference for log4net.dll from the main library, and reference the second library only if you'll need stuff tied to part that need log4net.dll.
Good way how to handle such cases is dependency injection - take a look at Enterprise Library (unity container) - though that will give you one extra dll :)
Using Unity Container:
You'll have Library1 with ILog4NetUsingInterface
In Library2 you'll have class Log4NetUsingClass : ILog4NetUsingInterface
In Library2 you'll have bootstrapper that will register Log4NetUsingClass as implementation of ILog4NetUsingInterface
public static class Bootstrapper {
public static void Init() {
ServiceLocator.IoC.RegisterSingleton<ILog4NetUsingInterface, Log4NetUsingClass>();
}
}
This Init method you'll call only if you need to use the Log4NetUsingClass
In every other library you can just call
ServiceLocator.IoC.Retrieve<ILog4NetUsingInterface>()
(If you won't call bootstrapper it will give you runtime error.)
Is there any way to change my class library program into an .exe or a click once-application? It is Currently a dll.
I am able to create a click once app but it is not working after installation.
In the properties of the project -> application tag, change the Output type to console Application. Anyway, you need to create a static Main() method as a starting point.
static void Main(string[] args)
{
}
You can change the output type of your project in it's settings, then add a main entrypoint, as others have mentioned (Note, you want "Windows application", not "Console Application" here):
If you can't change the source for some reason, you can create a new very simple application (an .exe), and call public methods in your .dll from it:
namespace YourNamespace
{
internal class YourApp
{
private static void Main(string[] args)
{
// Call your function here.
}
}
}
To do this, you just need to include a reference to the existing .dll into this new application.
Rather than changing it to an EXE - create a new project (Winform App, WPF, Console App, whatever) and reference your DLL to use the classes from it.
If you convert your DLL to an EXE then you lose (or at least significantly hinder) the ability to use those classes in any other application.
Keep non-UI classes in a DLL and only put UI-layer classes and controls in the executable.
Within dotnet core, just add this to the csproj, ideally within the first PropertyGroup:
<OutputType>Exe</OutputType>
Just watch out if your target framework was netstandard, that of course will not work (!).