在尝试从单独的DLL加载接口时,使用Visual Studio 2017RC(1月27日版本)的dotnet核心c#控制台应用程序遇到很多麻烦(项目是同一解决方案的一部分)。我按照Visual Studio 2017RC的说明在此处设置了dotnet核心:https://www.microsoft.com/net/core#windowsvs2017
主要应用:
public class Core
{
public static void Main(string[] args)
{
Console.WriteLine("Starting...");
// Setup PubSub
var pubSub = new PubSub();
}
}
public class PubSub : IPubSub
{
// Subscription table
private static ConcurrentDictionary<ChannelKey, ChannelSub> subscriptions = new ConcurrentDictionary<ChannelKey, ChannelSub>();
// User group table
private static ConcurrentDictionary<string, List<string>> clientGroups = new ConcurrentDictionary<string, List<string>>();
public PubSub()
{
try
{
List<string> users = new List<string>();
clientGroups["ADMINS"] = new List<string> { "PubSub.myClient" };
AddUpdChannel(new ChannelKey
{
network = Core.networkName,
category = "LIGHTING",
className = "CBUS",
instance = "MASTERCOCOON"
}, new ChannelSub
{
auth = new List<AccessAttribs>
{
new AccessAttribs
{
name = "ADMINS",
access = "RW"
}
},
clients = new List<AccessAttribs>
{
new AccessAttribs
{
name = "PubSub.myClient",
access = "RW"
}
}
});
Subscribe("myClient", new ChannelKey
{
network = Core.networkName,
category = "LIGHTING",
className = "CBUS",
instance = "MASTERCOCOON"
});
}
catch (Exception ex)
{
throw ex;
}
}
public bool Publish(string clientName, ChannelKey channel, string message, [CallerFilePath] string caller = "")
{
Logger.LogInformation("Client: " + clientName + " published to: " + channel.instance + " TEST");
return true;
}
// Channels must be created before subscribed to.
public bool AddUpdChannel(ChannelKey channel, ChannelSub channelSub, [CallerMemberName] string caller = "")
{
channelSub.author = caller; // Enforce author as caller, regardless of setting passed.
subscriptions[channel] = channelSub;
return true;
}
// Subscribe to channel for Ext/Plug.Client. Return null if channel does not exist else return access rights ("", R, RW) and update any old entries or add new
public string Subscribe(string clientName, ChannelKey channel, [CallerFilePath] string caller = "")
{
string access = "";
var fullClientName = Path.GetFileNameWithoutExtension(caller) + "." + clientName;
if (subscriptions.TryGetValue(channel, out var subscription)) // Get channel subscription info
{
foreach (var subGroup in subscription.auth) // Get access rights for group client is a member of
{
clientGroups.TryGetValue(subGroup.name, out var clientGroup); // Lookup clients associated with group
if (clientGroup.Contains(fullClientName))
{
access = subGroup.access;
if (subGroup.access == "RW") break; // RW access takes precidence if user is a member of multiple groups
}
}
if (access != "") // Some access allowed so setup
{
var newAccess = new AccessAttribs
{
name = fullClientName,
access = access
};
var exists = subscription.clients.FindIndex(x => x.name == fullClientName); // Look for fullClientName already in list (assume there could be any access strings)
if (exists != -1)
{
subscription.clients[exists] = newAccess; // Update if existing
}
else
{
subscription.clients.Add(newAccess); // Add if new
}
subscriptions[channel] = subscription; // Update subscription with new client access info
}
return access;
}
return null; // subscription does not exist
}
}
接口在单独的项目中定义如下:
namespace Interfaces
{
public interface IExtension
{
string ExtStart(IPubSub myHost);
string ExtStop(string param);
}
public interface IPubSub
{
bool AddUpdChannel(ChannelKey channel, ChannelSub channelSub, [CallerMemberName] string caller = "");
string Subscribe(string clientName, ChannelKey channel, [CallerFilePath] string caller = "");
bool Publish(string clientName, ChannelKey channel, string message, [CallerFilePath] string caller = "");
}
public struct ChannelKey
{
public string network;
public string category;
public string className;
public string instance;
}
public struct AccessAttribs
{
public string name;
public string access;
}
public class ChannelSub
{
public bool active = true;
public string desc = "";
public string type = "GENERIC";
public string author = "";
public List<AccessAttribs> clients = new List<AccessAttribs>(); // List of clients subscribed & their access rights. This is set when subscribing to enable fast lookup when processing messages
public List<AccessAttribs> auth = new List<AccessAttribs>(); // When subscribing, clients must be a member of one of these groups & will get the access rights of that group
public List<KeyValuePair<string, string>> attribs = new List<KeyValuePair<string, string>>();
}
解决方案构建正常,智能感知查找DLL中的所有接口定义,因此必须找到该文件。我已多次清理/重建/检查文件位置,这很好。此外,我可以将此代码剪切/粘贴到非Core .NET项目中,并且工作正常。
首次在调试模式下启动时报告的错误是:
System.IO.FileNotFoundException 'Could not load file or assembly Commons, Version=1.0.0.0,
culture=neutral, PublicKeyToken=null". The system cannot find the file specified.
主要项目的csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="Commons">
<HintPath>..\Commons\bin\Debug\netcoreapp1.1\Commons.dll</HintPath>
<Private>true</Private>
</Reference>
</ItemGroup>
</Project>
csproj用于接口DLL(Commons.DLL)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
</Project>
我已多次重建此项目,多次重新安装VS 2017RC并且我无法摆脱接口引用DLL的文件未找到错误。
答案 0 :(得分:1)
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
Microsoft.Extensions.Configuration
之前似乎缺少ItemGroup
。
我建议您引用项目本身而不是引用debug
dll。结果csproj
应如下所示:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Commons\Commons.csproj" />
</ItemGroup>
</Project>
您的Common
项目是库,因此它不应该是netcoreapp
,但它应该是.Net标准库。这就是它的csproj
应该是这样的:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NETStandard.Library" Version="1.6" />
</ItemGroup>
</Project>
现在您应该能够成功编译并运行代码。