如何添加对 class 库的引用以及该库的所有引用?
How to add a reference to a class library with all references of this library?
我试着解释一下我的问题。
我有自己的 windows 服务(WS)。 WS 指的是 Helpers.dll
。 Helpers.dll
这是我自己的 class 图书馆 有几个参考。其中一个参考文献是 System.Web.Mvc.dll
.
例如,如果我将 Helpers.dll
上的引用添加到我的 WS,所有来自 Helpers.dll
的引用都不会添加到 WS.(我认为在大多数情况下这种行为是正确的)
我正在尝试在 Syste.Web.Mvc.dll
(Helpers.csproj
)
上设置 Copy Local = True
引用的内部属性
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
</Reference>
不过没有任何变化。
如果没有放置在 Helpers.dll 中的引用,我的 WS 将无法正常工作。
TypeInitializationException
将被扔在 rintume 中。 (异常发生在试图执行 AppDomain.CurrentDomain.GetAssemblies()
方法的静态构造函数中,其中一个程序集是 Helpers.dll
,link 在 System.Web.Mvc.dll
上)
如何添加一个 class 库引用以及该库的所有引用?
确切地说,我可以在 WS 项目中手动添加此引用 (System.Web.Mvc.dll
),我想通过设置或 .config
文件来完成此操作或者其他东西。
实际上,我使用下面的代码来动态解析程序集:
无论如何,在解析程序集期间第一次使用 AssemblyHelpers
class 之后,我在 WS 中得到了异常 - 我的 WS 使用 Helpers.dll
使用 System.Web.Mvc.dll
(这个 dll
只放在 Helpers 项目的 bin 文件夹中,不放在 bin 中WS 的来源)。
但是我的 WS 也使用 AssemblyHelpers
class 试图加载 System.Web.Mvc.dll
(首先,自定义程序集解析器加载 Helpers.dll
然后来自此 dll
的所有引用,包括 System.Web.Mvc.dll
) 并获得异常 (Description: The process was terminated due to an unhandled exception.Exception Info: System.TypeInitializationException
)。 \
System.Web.Mvc.dll
不在我的 WS.
的 bin 文件夹中
public static class AssemblyHelper
{
private static readonly object _syncLock = new object();
private static readonly List<Assembly> _assemblies = new List<Assembly>();
public static ICollection<Assembly> SyncronizedList
{
get
{
lock (_syncLock)
{
return new List<Assembly>(_assemblies);
}
}
}
static AssemblyHelper()
{
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(OnAssemblyLoad);
AppDomain.CurrentDomain.DomainUnload += new EventHandler(OnDomainUnload);
// explicitly register previously loaded assemblies since they was not registered yet
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
RegisterAssembly(assembly);
}
}
private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
if (RegisterAssembly(args.LoadedAssembly))
{
ExecuteAllExecuteOnAssemblyLoadMethods(args.LoadedAssembly);
}
}
private static void OnDomainUnload(object sender, EventArgs args)
{
foreach (Assembly assembly in SyncronizedList)
{
ExecuteAllExecuteOnDomainUnloadMethods(assembly);
}
}
public static bool RegisterAssembly(Assembly assembly)
{
if (assembly == null)
{
throw new ArgumentNullException("assembly");
}
lock (_syncLock)
{
if (_assemblies.Contains(assembly))
{
return false;
}
else
{
_assemblies.Add(assembly);
ExecuteAllExecuteOnAssemblyLoadMethods(assembly);
return true;
}
}
}
private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
if (RegisterAssembly(args.LoadedAssembly))
{
ExecuteAllExecuteOnAssemblyLoadMethods(args.LoadedAssembly);
}
}
private static void OnDomainUnload(object sender, EventArgs args)
{
foreach (Assembly assembly in SyncronizedList)
{
ExecuteAllExecuteOnDomainUnloadMethods(assembly);
}
}
public static ICollection<MethodInfo> FindAllMethods(Assembly assembly, Type attributeType)
{
String assemblyName = "unknown";
String attributeTypeName = String.Empty;
try
{
if (assembly == null)
{
throw new ArgumentNullException("assembly");
}
assemblyName = assembly.FullName;
if (attributeType == null)
{
throw new ArgumentNullException("attributeType");
}
attributeTypeName = attributeType.FullName;
List<MethodInfo> lst = new List<MethodInfo>();
foreach (Type type in assembly.GetTypes())
{
foreach (MethodInfo mi in type.GetMethods(
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
{
if (Attribute.IsDefined(mi, attributeType))
{
lst.Add(mi);
}
}
}
return lst;
}
catch (Exception ex)
{
//exception
}
}
public static int ExecuteAllMethods(Assembly assembly, Type attributeType)
{
int count = 0;
foreach (MethodInfo mi in FindAllMethods(assembly, attributeType))
{
try
{
mi.Invoke(null, null);
count++;
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("Failed to execute method {0} of {1}, reason: {2}",
mi.Name, mi.DeclaringType, Converter.GetExceptionMessageRecursive(ex)));
}
}
return count;
}
public static ICollection<MethodInfo> FindAllExecuteOnAssemblyLoadMethods(Assembly assembly)
{
return FindAllMethods(assembly, typeof(Attributes.ExecuteOnAssemblyLoadAttribute));
}
public static ICollection<MethodInfo> FindAllExecuteOnDomainUnloadMethods(Assembly assembly)
{
return FindAllMethods(assembly, typeof(Attributes.ExecuteOnDomainUnloadAttribute));
}
public static int ExecuteAllExecuteOnAssemblyLoadMethods(Assembly assembly)
{
return ExecuteAllMethods(assembly, typeof(Attributes.ExecuteOnAssemblyLoadAttribute));
}
public static int ExecuteAllExecuteOnDomainUnloadMethods(Assembly assembly)
{
return ExecuteAllMethods(assembly, typeof(Attributes.ExecuteOnDomainUnloadAttribute));
}
}
How to add a reference to a class library with all references of this library?
您不应该添加您拥有的每个传递依赖项作为程序集引用。需要引用才能从另一个程序集中导入类型并使其在您的代码中可用。
我认为真正的问题是将依赖程序集部署到构建文件夹的过程。尝试在问题中使用一些建议:MSBuild doesn't pick up references of the referenced project
处理传递依赖项(将其正确部署到每个依赖项目)的现代方法是使用包管理器。 NuGet 是用于此目的的事实标准。 DNX 项目系统中的许多创新也旨在解决此类问题,并使用 NuGet 包作为第一个 class 构建和部署实体。
首先感谢@Nipheris 的解答和建议使用Nuget。使用 Nuget 对我很有帮助。
无论如何,我一直收到错误消息。我认为尝试使用 unity 而不是自定义依赖项解析器(AssemblyHelper
class 是其中的一部分)助手。在我看来,自定义依赖解析器的使用一直让我出错。
我试着解释一下我的问题。
我有自己的 windows 服务(WS)。 WS 指的是 Helpers.dll
。 Helpers.dll
这是我自己的 class 图书馆 有几个参考。其中一个参考文献是 System.Web.Mvc.dll
.
例如,如果我将 Helpers.dll
上的引用添加到我的 WS,所有来自 Helpers.dll
的引用都不会添加到 WS.(我认为在大多数情况下这种行为是正确的)
我正在尝试在 Syste.Web.Mvc.dll
(Helpers.csproj
)
Copy Local = True
引用的内部属性
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
</Reference>
不过没有任何变化。
如果没有放置在 Helpers.dll 中的引用,我的 WS 将无法正常工作。
TypeInitializationException
将被扔在 rintume 中。 (异常发生在试图执行 AppDomain.CurrentDomain.GetAssemblies()
方法的静态构造函数中,其中一个程序集是 Helpers.dll
,link 在 System.Web.Mvc.dll
上)
如何添加一个 class 库引用以及该库的所有引用?
确切地说,我可以在 WS 项目中手动添加此引用 (System.Web.Mvc.dll
),我想通过设置或 .config
文件来完成此操作或者其他东西。
实际上,我使用下面的代码来动态解析程序集:
无论如何,在解析程序集期间第一次使用 AssemblyHelpers
class 之后,我在 WS 中得到了异常 - 我的 WS 使用 Helpers.dll
使用 System.Web.Mvc.dll
(这个 dll
只放在 Helpers 项目的 bin 文件夹中,不放在 bin 中WS 的来源)。
但是我的 WS 也使用 AssemblyHelpers
class 试图加载 System.Web.Mvc.dll
(首先,自定义程序集解析器加载 Helpers.dll
然后来自此 dll
的所有引用,包括 System.Web.Mvc.dll
) 并获得异常 (Description: The process was terminated due to an unhandled exception.Exception Info: System.TypeInitializationException
)。 \
System.Web.Mvc.dll
不在我的 WS.
public static class AssemblyHelper
{
private static readonly object _syncLock = new object();
private static readonly List<Assembly> _assemblies = new List<Assembly>();
public static ICollection<Assembly> SyncronizedList
{
get
{
lock (_syncLock)
{
return new List<Assembly>(_assemblies);
}
}
}
static AssemblyHelper()
{
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(OnAssemblyLoad);
AppDomain.CurrentDomain.DomainUnload += new EventHandler(OnDomainUnload);
// explicitly register previously loaded assemblies since they was not registered yet
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
RegisterAssembly(assembly);
}
}
private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
if (RegisterAssembly(args.LoadedAssembly))
{
ExecuteAllExecuteOnAssemblyLoadMethods(args.LoadedAssembly);
}
}
private static void OnDomainUnload(object sender, EventArgs args)
{
foreach (Assembly assembly in SyncronizedList)
{
ExecuteAllExecuteOnDomainUnloadMethods(assembly);
}
}
public static bool RegisterAssembly(Assembly assembly)
{
if (assembly == null)
{
throw new ArgumentNullException("assembly");
}
lock (_syncLock)
{
if (_assemblies.Contains(assembly))
{
return false;
}
else
{
_assemblies.Add(assembly);
ExecuteAllExecuteOnAssemblyLoadMethods(assembly);
return true;
}
}
}
private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
if (RegisterAssembly(args.LoadedAssembly))
{
ExecuteAllExecuteOnAssemblyLoadMethods(args.LoadedAssembly);
}
}
private static void OnDomainUnload(object sender, EventArgs args)
{
foreach (Assembly assembly in SyncronizedList)
{
ExecuteAllExecuteOnDomainUnloadMethods(assembly);
}
}
public static ICollection<MethodInfo> FindAllMethods(Assembly assembly, Type attributeType)
{
String assemblyName = "unknown";
String attributeTypeName = String.Empty;
try
{
if (assembly == null)
{
throw new ArgumentNullException("assembly");
}
assemblyName = assembly.FullName;
if (attributeType == null)
{
throw new ArgumentNullException("attributeType");
}
attributeTypeName = attributeType.FullName;
List<MethodInfo> lst = new List<MethodInfo>();
foreach (Type type in assembly.GetTypes())
{
foreach (MethodInfo mi in type.GetMethods(
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
{
if (Attribute.IsDefined(mi, attributeType))
{
lst.Add(mi);
}
}
}
return lst;
}
catch (Exception ex)
{
//exception
}
}
public static int ExecuteAllMethods(Assembly assembly, Type attributeType)
{
int count = 0;
foreach (MethodInfo mi in FindAllMethods(assembly, attributeType))
{
try
{
mi.Invoke(null, null);
count++;
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("Failed to execute method {0} of {1}, reason: {2}",
mi.Name, mi.DeclaringType, Converter.GetExceptionMessageRecursive(ex)));
}
}
return count;
}
public static ICollection<MethodInfo> FindAllExecuteOnAssemblyLoadMethods(Assembly assembly)
{
return FindAllMethods(assembly, typeof(Attributes.ExecuteOnAssemblyLoadAttribute));
}
public static ICollection<MethodInfo> FindAllExecuteOnDomainUnloadMethods(Assembly assembly)
{
return FindAllMethods(assembly, typeof(Attributes.ExecuteOnDomainUnloadAttribute));
}
public static int ExecuteAllExecuteOnAssemblyLoadMethods(Assembly assembly)
{
return ExecuteAllMethods(assembly, typeof(Attributes.ExecuteOnAssemblyLoadAttribute));
}
public static int ExecuteAllExecuteOnDomainUnloadMethods(Assembly assembly)
{
return ExecuteAllMethods(assembly, typeof(Attributes.ExecuteOnDomainUnloadAttribute));
}
}
How to add a reference to a class library with all references of this library?
您不应该添加您拥有的每个传递依赖项作为程序集引用。需要引用才能从另一个程序集中导入类型并使其在您的代码中可用。
我认为真正的问题是将依赖程序集部署到构建文件夹的过程。尝试在问题中使用一些建议:MSBuild doesn't pick up references of the referenced project
处理传递依赖项(将其正确部署到每个依赖项目)的现代方法是使用包管理器。 NuGet 是用于此目的的事实标准。 DNX 项目系统中的许多创新也旨在解决此类问题,并使用 NuGet 包作为第一个 class 构建和部署实体。
首先感谢@Nipheris 的解答和建议使用Nuget。使用 Nuget 对我很有帮助。
无论如何,我一直收到错误消息。我认为尝试使用 unity 而不是自定义依赖项解析器(AssemblyHelper
class 是其中的一部分)助手。在我看来,自定义依赖解析器的使用一直让我出错。