public void SupportsInjectDirective() { // Arrange/Act 1: Compilation var componentType = CompileToComponent( $"@inject {FullTypeName<IMyService1>()} MyService1\n" + $"@inject {FullTypeName<IMyService2>()} MyService2\n" + $"Hello from @MyService1 and @MyService2").GetType(); // Assert 1: Compiled type has correct properties var propertyFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.NonPublic; var injectableProperties = componentType.GetProperties(propertyFlags) .Where(p => p.GetCustomAttribute <InjectAttribute>() != null); Assert.Collection(injectableProperties.OrderBy(p => p.Name), property => { Assert.Equal("MyService1", property.Name); Assert.Equal(typeof(IMyService1), property.PropertyType); Assert.False(property.GetMethod.IsPublic); Assert.False(property.SetMethod.IsPublic); }, property => { Assert.Equal("MyService2", property.Name); Assert.Equal(typeof(IMyService2), property.PropertyType); Assert.False(property.GetMethod.IsPublic); Assert.False(property.SetMethod.IsPublic); }); // Arrange/Act 2: DI-supplied component has correct behavior var serviceProvider = new TestServiceProvider(); serviceProvider.AddService <IMyService1>(new MyService1Impl()); serviceProvider.AddService <IMyService2>(new MyService2Impl()); var componentFactory = new ComponentFactory(serviceProvider); var component = componentFactory.InstantiateComponent(componentType); var frames = GetRenderTree(component); // Assert 2: Rendered component behaves correctly Assert.Collection(frames, frame => AssertFrame.Text(frame, "Hello from "), frame => AssertFrame.Text(frame, typeof(MyService1Impl).FullName), frame => AssertFrame.Text(frame, " and "), frame => AssertFrame.Text(frame, typeof(MyService2Impl).FullName)); }