如何添加对 class 库的引用以及该库的所有引用?

How to add a reference to a class library with all references of this library?

我试着解释一下我的问题。

我有自己的 windows 服务(WS)。 WS 指的是 Helpers.dllHelpers.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 是其中的一部分)助手。在我看来,自定义依赖解析器的使用一直让我出错。