好吧,我不知道为什么会这样。
我设置了一个属性,在我设置之后,它在另一个类中为null。使用调试器逐步调试它只显示它的设置,并在其他类中显示为null。
这是我的代码:(剥离所有不必要的代码)
public class SnakeGame : SenseHatSnake, ISnakeGame
{
private readonly IBody _body;
public SnakeGame(ISenseHat senseHat, IBody body)
: base(senseHat)
{
_body = body;
}
private void UpdateGame(Object state)
{
_movement.PreviousPositions.Add(new Position()
{
X = _movement.X,
Y = _movement.Y
});
if (_body.DetectCollision(_movement.X, _movement.Y))
{
GameOver();
}
}
}
它发生在身体类的DetectCollision
。
public class Body : IBody
{
private readonly IMovement _movement;
public Body(IMovement movement)
{
_movement = movement;
}
public bool DetectCollision(int x, int y)
{
for (int i = 1; i < Length + 1; i++)
{
if (_movement.PreviousPositions.Count > i)
{
int bX = _movement.PreviousPositions[_movement.PreviousPositions.Count - i - 1].X;
int bY = _movement.PreviousPositions[_movement.PreviousPositions.Count - i - 1].Y;
if (bX == x && bY == y)
{
return true;
}
}
}
return false;
}
}
我刚刚设置了_movement.PreviousPositions
,我可以在调试器中看到它,但是一旦它在Body
中,_movement.PreviousPositions
就是null。
Movement.cs:
public class Movement : IMovement
{
public List<Position> PreviousPositions { get; set; }
}
注意:
我正在使用DI,我在那里做错了吗? (Autofac)
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
var builder = new ContainerBuilder();
builder.RegisterType<Body>().As<IBody>();
builder.RegisterType<Display>().As<IDisplay>();
builder.RegisterType<Draw>().As<IDraw>();
builder.RegisterType<Food>().As<IFood>();
builder.RegisterType<Movement>().As<IMovement>();
builder.RegisterType<SnakeGame>().As<ISnakeGame>();
builder.RegisterType<ISenseHat>().As<ISenseHat>();
var container = builder.Build();
var body = container.Resolve<IBody>();
var display = container.Resolve<IDisplay>();
var draw = container.Resolve<IDraw>();
var food = container.Resolve<IFood>();
var movement = container.Resolve<IMovement>();
Task.Run(async () =>
{
ISenseHat senseHat = await SenseHatFactory.GetSenseHat().ConfigureAwait(false);
var snakeGame = new SnakeGame(senseHat, body, display, draw, food, movement);
snakeGame.Run();
});
}
}
默认情况下,Autofac将组件注册为InstancePerDependency
,因此此代码将获得两个唯一的实例:
var a = container.Resolve<IExample>();
var b = container.Resolve<IExample>();
如果你想要一个单例,你需要使用.SingleInstance()
注册这个对象:
builder.RegisterType<Movement>().As<IMovement>().SingleInstance();
这应该解决你的问题,虽然我注意到你似乎通过手动解决每个服务使用service locator anti-pattern。您可以将代码更改为:
var builder = new ContainerBuilder();
builder.RegisterType<Body>().As<IBody>();
builder.RegisterType<Display>().As<IDisplay>();
builder.RegisterType<Draw>().As<IDraw>();
builder.RegisterType<Food>().As<IFood>();
builder.RegisterType<Movement>().As<IMovement>().SingleInstance();
builder.RegisterType<SnakeGame>().As<ISnakeGame>();
builder.RegisterInstance<ISenseHat>(await SenseHatFactory.GetSenseHat().ConfigureAwait(false));
var container = builder.Build();
var snakeGame = container.Resolve<ISnakeGame>();
snakeGame.Run();
如果请求类型,RegisterType
将解析为新实例。如果您想在您的班级中共享一个实例,请使用RegisterInstance
代替您的Movement类,例如
var movement = new Movement();
var builder = new ContainerBuilder();
builder.RegisterType<Body>().As<IBody>();
builder.RegisterType<Display>().As<IDisplay>();
builder.RegisterType<Draw>().As<IDraw>();
builder.RegisterType<Food>().As<IFood>();
**builder.RegisterInstance<IMovement>(movement);**
builder.RegisterType<SnakeGame>().As<ISnakeGame>();
builder.RegisterType<ISenseHat>().As<ISenseHat>();
var container = builder.Build();