gpt4 book ai didi

c# - 有默认构造函数时没有默认构造函数报错

转载 作者:行者123 更新时间:2023-11-30 20:50:37 26 4
gpt4 key购买 nike

编辑:将在 SO 上公开生产代码!希望没有人窃取我的 secret !

我有一个 Controller 类,用于使用 Modbus 协议(protocol)通过 TCP 与设备通信。我使用 NModbus 库。

Controller 类实现的接口(interface)如下:

public interface CoilReader
{
bool[] Read(ushort startAddress, ushort numberOfCoils);
}

public interface CoilWriter
{
void WriteSingle(ushort address, bool value);

void WriteMultiple(ushort startAddress, bool[] values);
}

public interface HoldingRegisterReader
{
ushort[] Read(ushort startAddress, ushort numberOfRegisters);
}

public interface HoldingRegisterWriter
{
void WriteSingle(ushort address, ushort value);

void WriteMultiple(ushort startAddress, ushort[] values);
}

public interface InputReader
{
bool[] Read(ushort startAddress, ushort numberOfCoils);
}

public interface InputRegisterReader
{
ushort[] Read(ushort startAddress, ushort numberOfRegisters);
}

public interface ConnectionInfo
{
string IP { get; set; }
}

这是 Controller 类。

using System;
using System.Net.Sockets;
using System.Reflection;
using global::Modbus.Device;

public class Controller
: ConnectionInfo,
HoldingRegisterReader,
InputRegisterReader,
CoilReader,
InputReader,
CoilWriter,
HoldingRegisterWriter
{
static Controller()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => loadEmbeddedAssembly(e.Name);
}

public virtual string IP
{
get
{
return this.ip;
}

set
{
this.ip = value;
}
}

public virtual ushort[] ReadHoldingRegisters(ushort startAddress, ushort numberOfRegisters)
{
using (var connection = this.createDeviceConnection())
{
return connection.ReadHoldingRegisters(startAddress, numberOfRegisters);
}
}

public virtual ushort[] ReadInputRegisters(ushort startAddress, ushort numberOfRegisters)
{
using (var connection = this.createDeviceConnection())
{
return connection.ReadInputRegisters(startAddress, numberOfRegisters);
}
}

public virtual bool[] ReadCoils(ushort startAddress, ushort numberOfCoils)
{
using (var connection = this.createDeviceConnection())
{
return connection.ReadCoils(startAddress, numberOfCoils);
}
}

public virtual bool[] ReadInputs(ushort startAddress, ushort numberOfInputs)
{
using (var connection = this.createDeviceConnection())
{
return connection.ReadInputs(startAddress, numberOfInputs);
}
}

public virtual void WriteSingleCoil(ushort address, bool value)
{
using (var connection = this.createDeviceConnection())
{
connection.WriteSingleCoil(address, value);
}
}

public virtual void WriteMultipleCoils(ushort startAddress, bool[] values)
{
using (var connection = this.createDeviceConnection())
{
connection.WriteMultipleCoils(startAddress, values);
}
}

public virtual void WriteSingleHoldingRegister(ushort address, ushort value)
{
using (var connection = this.createDeviceConnection())
{
connection.WriteSingleRegister(address, value);
}
}

public virtual void WriteMultipleHoldingRegisters(ushort startAddress, ushort[] values)
{
using (var connection = this.createDeviceConnection())
{
connection.WriteMultipleRegisters(startAddress, values);
}
}

string ConnectionInfo.IP
{
get
{
return this.IP;
}

set
{
this.IP = value;
}
}

ushort[] HoldingRegisterReader.Read(ushort startAddress, ushort numberOfRegisters)
{
return this.ReadHoldingRegisters(startAddress, numberOfRegisters);
}

ushort[] InputRegisterReader.Read(ushort startAddress, ushort numberOfRegisters)
{
return this.ReadInputRegisters(startAddress, numberOfRegisters);
}

bool[] CoilReader.Read(ushort startAddress, ushort numberOfCoils)
{
return this.ReadCoils(startAddress, numberOfCoils);
}

bool[] InputReader.Read(ushort startAddress, ushort numberOfInputs)
{
return this.ReadInputs(startAddress, numberOfInputs);
}

void CoilWriter.WriteSingle(ushort address, bool value)
{
this.WriteSingleCoil(address, value);
}

void CoilWriter.WriteMultiple(ushort startAddress, bool[] values)
{
this.WriteMultipleCoils(startAddress, values);
}

void HoldingRegisterWriter.WriteSingle(ushort address, ushort value)
{
this.WriteSingleHoldingRegister(address, value);
}

void HoldingRegisterWriter.WriteMultiple(ushort startAddress, ushort[] values)
{
this.WriteMultipleHoldingRegisters(startAddress, values);
}

private ModbusIpMaster createDeviceConnection()
{
const int port = 502;
var client = new TcpClient();
client.BeginConnect(this.ip, port, null, null).AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2));
if (!client.Connected)
{
throw new Exception("Cannot connect to " + this.ip + ":" + port);
}

return ModbusIpMaster.CreateIp(client);
}

private static Assembly loadEmbeddedAssembly(string name)
{
if (name.EndsWith("Retargetable=Yes"))
{
return Assembly.Load(new AssemblyName(name));
}

var container = Assembly.GetExecutingAssembly();
var path = new AssemblyName(name).Name + ".dll";

using (var stream = container.GetManifestResourceStream(path))
{
if (stream == null)
{
return null;
}

var bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
return Assembly.Load(bytes);
}
}

private string ip;
}

在与包含此类及其接口(interface)的库相同的解决方案中的测试项目中创建的测试中,我没有收到以下错误。但是,在使用该库的不同解决方案的项目中,我得到以下信息:

------ Test started: Assembly: CareControls.IvisHmi.Tests.dll ------

Unknown .NET Framework Version: v4.5.1
Test 'CareControls.IvisHmi.Tests.Presenters.ModbusTcpTogglePresenterTests.FactMethodName' failed: FakeItEasy.Core.FakeCreationException :
Failed to create fake of type "CareControls.Modbus.Tcp.Controller".

Below is a list of reasons for failure per attempted constructor:
No constructor arguments failed:
No default constructor was found on the type CareControls.Modbus.Tcp.Controller.

If either the type or constructor is internal, try adding the following attribute to the assembly:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]


at FakeItEasy.Core.DefaultExceptionThrower.ThrowFailedToGenerateProxyWithResolvedConstructors(Type typeOfFake, String reasonForFailureOfUnspecifiedConstructor, IEnumerable`1 resolvedConstructors)
at FakeItEasy.Creation.FakeObjectCreator.TryCreateFakeWithDummyArgumentsForConstructor(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, String failReasonForDefaultConstructor, Boolean throwOnFailure)
at FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, Boolean throwOnFailure)
at FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type typeOfFake, FakeOptions options)
at FakeItEasy.Creation.DefaultFakeCreatorFacade.CreateFake[T](Action`1 options)
at FakeItEasy.A.Fake[T]()
Presenters\ModbusTcpTogglePresenterTests.cs(22,0): at CareControls.IvisHmi.Tests.Presenters.ModbusTcpTogglePresenterTests.FactMethodName()

0 passed, 1 failed, 0 skipped, took 0.93 seconds (xUnit.net 1.9.2 build 1705).

这是测试:

namespace CareControls.IvisHmi.Tests.Presenters
{
using CareControls.IvisHmi.Framework;
using CareControls.IvisHmi.Presenters;
using CareControls.IvisHmi.UI;
using CareControls.Modbus.Tcp;
using FakeItEasy;
using Ploeh.AutoFixture;
using Xunit;

public class ModbusTcpTogglePresenterTests
{
[Fact]
public void FactMethodName()
{
A.Fake<Controller>();
}
}
}

为什么 FakeItEasy 认为类上没有默认构造函数?

抱歉发了这么大的帖子,但要求我包含代码。

编辑:如果我添加 new Controller() 测试通过在 A.Fake<Controller>() 之前行:

namespace CareControls.IvisHmi.Tests.Presenters
{
using CareControls.IvisHmi.Framework;
using CareControls.IvisHmi.Presenters;
using CareControls.IvisHmi.UI;
using CareControls.Modbus.Tcp;
using FakeItEasy;
using Ploeh.AutoFixture;
using Xunit;

public class ModbusTcpTogglePresenterTests
{
[Fact]
public void FactMethodName()
{
new Controller();
A.Fake<Controller>();
}
}
}

最佳答案

据此:

Faking/mocking an interface gives "no default constructor" error, how can that be?

有一个错误可以给出错误的异常信息。他们说,在那种情况下,仍然应该有一些东西导致抛出异常。

我建议的事情:

  • 添加显式默认构造函数有帮助吗?
  • 能否正常成功实例化该类?
  • 你能用反射或Activator.CreateInstance成功实例化类吗?

关于c# - 有默认构造函数时没有默认构造函数报错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22413998/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com