属性集,在其他类中为null。 C#

问题描述 投票:1回答:2

好吧,我不知道为什么会这样。

我设置了一个属性,在我设置之后,它在另一个类中为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();
        });


    }


}
c# dependency-injection uwp autofac
2个回答
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
投票

如果请求类型,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();
© www.soinside.com 2019 - 2024. All rights reserved.