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

时间:2018-08-31 01:47:52

标签: c# dependency-injection uwp autofac

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

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


    }


}

2 个答案:

答案 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();