Можно ли превратить одну и ту же DLL в консольное приложение и в зависимость NuGet?
У меня есть проект, нацеленный на.NET Standard 1.5, который развернут как несколько библиотек DLL на NuGet. Проект был портирован с Java. Внутри некоторые классы проекта статичны Main()
методы, которые предназначены для запуска из командной строки.
В.NET Core кажется, что есть 2 способа скомпилировать DLL:
<OutputType>Exe</OutputType>
- компилируется в исполняемое консольное приложение (DLL)<OutputType>Library</OutputType>
(по умолчанию) - компилируется в библиотеку классов (DLL)
Что мне интересно, есть ли способ скомпилировать DLL, чтобы ее можно было использовать в любом случае, не имея 2 отдельных (сбивающих с толку) DLL?
По сути, я пытаюсь получить функциональность, аналогичную той, что есть в Java, где на пакет может ссылаться приложение или запускать из командной строки (и указывать цель ввода в командной строке).
пример
Например, в Java есть файлы, которые являются частью пакета и содержат статический Main(object[] args)
метод.
public class SomeClass
{
public void DoSomething(string arg1, string arg2, string arg3)
{
// implementation...
}
public static void Main(object[] args)
{
// parse args...
new SomeClass().DoSomething(arg1, arg2, arg3);
}
}
На DoSomething ссылаются в других местах пакета (что эквивалентно тому, как сейчас выглядят мои пакеты NuGet). Однако в Java Main(object[] args)
можно запустить из командной строки, как...
java <package>.jar <namespace>.SomeClass [args]
без необходимости загружать или устанавливать что-либо дополнительно. В конце концов, если компонент, для которого пользователь хочет выполнить команду, есть, все зависимости также присутствуют.
В идеале, я могу просто использовать аналогичные функции в ядре dotnet...
dotnet <assembly>.dll <namespace>.SomeClass [args]
что было бы предпочтительнее, чем создавать отдельную DLL-оболочку вокруг всего этого, или создать отдельный проект, который должен выбрать все зависимости SomeClass
поэтому они все собраны в одну сборку (консольное приложение).
Кроме того, есть несколько статических Main()
методы для пакета, которые, кажется, были поддержаны в.NET Core ранее, о чем мой другой вопрос.
2 ответа
В.Net Standard/Core ваш лучший вариант - создать второй проект, который компилируется в EXE-файл, у которого есть простой метод Main(), который указывает на версию библиотеки. Это не идеально, но проблема в том, как работает среда выполнения.Net core. Проект, нацеленный на.Net Standard, может использоваться всеми проектами, совместимыми с этой стандартной версией. На проект, нацеленный на конкретный.NetCoreApp, могут ссылаться только другие.NetCoreApps, поэтому вы не получите преимущества от нацеливания на стандарт.
Для развертывания упаковки / NuGet версия консольного приложения может быть помещена в папку инструментов NuGet, чтобы конечный пользователь мог ее использовать. Вы на самом деле не хотите, чтобы исполняемые файлы были развернуты через стандартную папку содержимого NuGet, потому что она не будет действительно следовать стандарту и вводить в заблуждение ваших пользователей NuGet.
Вы получаете его бесплатно с.Net EXE (который является просто сборкой так же, как DLL и на которую можно ссылаться как таковой).
Чтобы приблизиться к DLL, вам нужно сделать так, чтобы.Net DLL можно было использовать из командной строки. Предоставление некоторой нативно-совместимой точки входа и использование rundll32 для доступа к ней из командной строки - это вариант для достижения этого: необходимо запустить aC# dll из командной строки.