好的,我不知道为什么会这样。
我设置了一个属性,设置完后,在另一个类中它为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();
}
}
}
它发生在body类的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
就为空。
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();
});
}
}
答案 0 :(得分:2)
默认情况下,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();
答案 1 :(得分:-1)
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();