![](/img/trans.png)
[英]Referencing a class library without having to reference the library's service references
[英]How to add a reference to a class library with all references of this library?
我試圖解釋我的問題。
我有自己的Windows服務( WS )。 該WS參考Helpers.dll
。 Helpers.dll
是我自己的類庫 ,具有多個引用。 此引用之一是System.Web.Mvc.dll
。
例如,如果我要在WS上添加對Helpers.dll
引用, Helpers.dll
會將來自Helpers.dll
所有引用添加到WS 。(在大多數情況下,我認為這種行為是正確的)
我正在嘗試在Syste.Web.Mvc.dll
( Helpers.csproj
)上Syste.Web.Mvc.dll
對引用的屬性內部的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
具有System.Web.Mvc.dll
上的鏈接)
如何使用該庫的所有引用添加類庫引用?
確實,我可以手動在WS項目中添加此引用( System.Web.Mvc.dll
),我想通過設置或.config
文件或其他方式來執行此操作。
實際上,我將以下代碼用於動態解析程序集:
無論如何,在解決程序集期間第一次使用AssemblyHelpers
類之后,我在WS中得到了異常-我的WS使用了使用System.Web.Mvc.dll
Helpers.dll
(此dll
僅放置在Helpers項目的bin文件夾中,放在WS的 bin foder中)。
但是我的WS還使用了一個AssemblyHelpers
類,該類嘗試加載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
。 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));
}
}
如何使用該庫的所有引用添加對類庫的引用?
您不應該將每個傳遞依賴項都添加為程序集引用。 需要引用才能從另一個程序集中導入類型並使其在您的代碼中可用。
我認為真正的問題是將依賴程序集部署到build文件夾的過程。 嘗試在問題中使用一些建議: MSBuild不獲取所引用項目的引用
處理傳遞依賴關系(將其正確部署到每個依賴項目中)的現代方法是使用包管理器。 NuGet是為此目的的實際標准。 DNX項目系統中的許多創新也旨在解決此類問題,並將NuGet軟件包用作一流的構建和部署實體。
首先,我要感謝@Nipheris提供使用Nuget的答案和建議。 使用Nuget確實對我有幫助。
無論如何,我一直在得到錯誤。 我認為嘗試使用統一代替自定義依賴項解析器( AssemblyHelper
類是其中的一部分)幫助器。 我認為,使用自定義依賴項解析器已經使我出錯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.