В.NET Core и.NET> 4 существует универсальный метод синтаксического анализа :
Enum.TryParse("Active", out StatusEnum myStatus);
Это также включает C#7, новый встроенный out
переменные, таким образом, это делает синтаксический анализ попытки, преобразование в явный перечислимый тип и initialises+populates myStatus
переменная.
, Если у Вас есть доступ к C#7 и последней.NET, это - лучший способ.
В.NET это довольно ужасно (до 4 или выше):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
я склонен упрощать это с:
public static T ParseEnum(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Тогда я могу сделать:
StatusEnum MyStatus = EnumUtil.ParseEnum("Active");
Одна опция, предложенная в комментариях, состоит в том, чтобы добавить расширение, которое достаточно просто:
public static T ToEnum(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum();
Наконец, можно хотеть иметь перечисление по умолчанию, чтобы использовать, если строка не может быть проанализирована:
public static T ToEnum(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse(value, true, out result) ? result : defaultValue;
}
, Который делает это вызовом:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
Однако я был бы тщательным добавлением дополнительного метода как это к string
как (без управления пространством имен), появится на всех экземплярах [1 110], содержат ли они перечисление или не (таким образом 1234.ToString().ToEnum(StatusEnum.None)
было бы допустимо, но бессмыслен). Это часто быть лучшим постараться не создавать помехи базовым классам Microsoft дополнительными методами, которые только применяются в очень определенных контекстах, если у Вашей всей группы разработчиков нет очень хорошего понимания того, что делают те расширения.
У меня была та же проблема, но я не использовал Кассини. Вместо этого у меня был собственный хостинг веб-сервера на основе System.Net.HttpListener
с поддержкой ASP.Net через System.Web.HttpRuntime
, работающей в другом домене приложений, созданном через System.Web.Hosting.ApplicationHost.CreateApplicationHost ()
. По сути, так работает Cassini, за исключением того, что Cassini работает на уровне сокетов и реализует множество функций, предоставляемых самим System.Net.HttpListener
.
В любом случае, для решения моей проблемы мне понадобилось вызвать System.Web.HttpRuntime.Close ()
перед тем, как позволить NUnit выгрузить мой домен приложения.
Мой WebServerHost
класс - это очень маленький класс, который позволяет маршалировать запросы в домен приложения, созданный System.Web.Hosting.ApplicationHost.CreateApplicationHost ()
.
using System;
using System.IO;
using System.Web;
using System.Web.Hosting;
public class WebServerHost :
MarshalByRefObject
{
public void
Close()
{
HttpRuntime.Close();
}
public void
ProcessRequest(WebServerContext context)
{
HttpRuntime.ProcessRequest(new WebServerRequest(context));
}
}
using System;
using System.IO;
using System.Web;
using System.Web.Hosting;
public class WebServerHost :
MarshalByRefObject
{
public void
Close()
{
HttpRuntime.Close();
}
public void
ProcessRequest(WebServerContext context)
{
HttpRuntime.ProcessRequest(new WebServerRequest(context));
}
}
Класс WebServerContext
- это просто оболочка вокруг экземпляра System.Net.HttpListenerContext
, производного от System.MarshalByRefObject, чтобы разрешить вызовам из нового домена хостинга ASP.Net для обратного вызова в мой домен.
using System;
using System.Net;
public class WebServerContext :
MarshalByRefObject
{
public
WebServerContext(HttpListenerContext context)
{
this.context = context;
}
// public methods and properties that forward to HttpListenerContext omitted
private HttpListenerContext
context;
}
Класс WebServerRequest
- это просто реализация абстрактного класса System.Web.HttpWorkerRequest
, который обращается в мой домен из домена хостинга ASP.Net через WebServerContext
WebServerContext
.
using System;
using System.IO;
using System.Web;
class WebServerRequest :
HttpWorkerRequest
{
public
WebServerRequest(WebServerContext context)
{
this.context = context;
}
// implementation of HttpWorkerRequest methods omitted; they all just call
// methods and properties on context
private WebServerContext
context;
}
Класс WebServer
- это контроллер для запуска и остановки веб-сервера. Когда началось, домен хостинга ASP.Net создается с моим классом WebServerHost
в качестве прокси для обеспечения взаимодействия. Также запускается экземпляр System.Net.HttpListener
, и запускается отдельный поток для приема соединений. Когда соединение установлено, рабочий поток запускается в пуле потоков для обработки запроса, снова через мой класс WebServerHost
. Наконец, когда веб-сервер останавливается, слушатель останавливается, контроллер ожидает выхода потока, принимающего соединения, а затем слушатель закрывается. Наконец, среда выполнения HTTP также закрывается через вызов метода WebServerHost.Close ()
.
using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Threading;
using System.Web.Hosting;
class WebServer
{
public static void
Start()
{
lock ( typeof(WebServer) )
{
// do not start more than once
if ( listener != null )
return;
// create web server host in new AppDomain
host =
(WebServerHost)ApplicationHost.CreateApplicationHost
(
typeof(WebServerHost),
"/",
Path.GetTempPath()
);
// start up the HTTP listener
listener = new HttpListener();
listener.Prefixes.Add("http://*:8182/");
listener.Start();
acceptConnectionsThread = new Thread(acceptConnections);
acceptConnectionsThread.Start();
}
}
public static void
Stop()
{
lock ( typeof(WebServer) )
{
if ( listener == null )
return;
// stop listening; will cause HttpListenerException in thread blocked on GetContext()
listener.Stop();
// wait connection acceptance thread to exit
acceptConnectionsThread.Join();
acceptConnectionsThread = null;
// close listener
listener.Close();
listener = null;
// close host
host.Close();
host = null;
}
}
private static WebServerHost
host = null;
private static HttpListener
listener = null;
private static Thread
acceptConnectionsThread;
private static void
acceptConnections(object state)
{
while ( listener.IsListening )
{
try
{
HttpListenerContext context = listener.GetContext();
ThreadPool.QueueUserWorkItem(handleConnection, context);
}
catch ( HttpListenerException e )
{
// this exception is ignored; it will be thrown when web server is stopped and at that time
// listening will be set to false which will end the loop and the thread
}
}
}
private static void
handleConnection(object state)
{
host.ProcessRequest(new WebServerContext((HttpListenerContext)state));
}
}
Наконец, этот класс Initialization
, помеченный NUnit [SetupFixture ], используется для запуска веб-сервера при запуске модульных тестов,