我有一个班级UserManagement
,并且总是希望得到相同的instance
(就像单身模式一样)。所以现在我的问题是,我总是得到一个名为“Singleton”的新instance
内容。我是StructureMap
的新手。我已尝试在网站上描述的两个版本(http://structuremap.github.io/object-lifecycle/)(http://structuremap.github.io/glossary/)。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Container container = new Container(new UserManagement());
//UserManagement instance = container.GetInstance<UserManagement>("Singleton");
UserManagement instance = container.GetInstance<UserManagement>();
MessageBox.Show(instance.Test);
}
}
public interface IUser
{
void DoSomethingFancy();
}
public class User : IUser
{
public void DoSomethingFancy()
{
}
}
public interface IDatabase
{
void DoSomething();
}
public class Database : IDatabase
{
public void DoSomething()
{
}
}
public class UserManagement : Registry
{
public string Test;
private Container _Container;
private IUser _User;
private IDatabase _Database;
public UserManagement()
{
_Container = new Container(_ =>
{
_.For<IUser>().Use<User>();
_.For<IDatabase>().Use<Database>();
});
_User = _Container.GetInstance<IUser>();
_Database = _Container.GetInstance<IDatabase>();
Test = DateTime.Now.ToString();
//For<UserManagement>().AddInstances(x =>
//{
// x.Type<UserManagement>().Named("Singleton");
//});
For<UserManagement>().Singleton();
}
}
我的解决方案有3个项目
Bootstrapper
)MainWindow.xaml
)LoginAction
- UserManagement
)public static class Bootstrapper
{
public static Container Container => _Container ?? (_Container = InitializeContainer());
private static Container _Container;
public static Func<Container> InitializeContainer;
}
public partial class App : Application
{
public App()
{
Bootstrapper.InitializeContainer += InitializeContainer;
}
private Container InitializeContainer()
{
Container container = new Container(c => c.Scan(scanner =>
{
scanner.TheCallingAssembly();
scanner.WithDefaultConventions();
scanner.AssembliesFromApplicationBaseDirectory();
}));
container.Configure(c =>
{
c.ForSingletonOf<UserManagement>();
c.For<IUser>().Use<UserAdv>();
}
);
return container;
}
}
<Window x:Class="Gui.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:myFramework="clr-namespace:MyFramework;assembly=MyFramework"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="383,228,0,0" VerticalAlignment="Top" Width="75">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<myFramework:LoginAction/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</Window>
public class LoginAction : TriggerAction<DependencyObject>
{
protected override void Invoke(object parameter)
{
UserManagement userManagement = Bootstrapper.Container.GetInstance<UserManagement>();
Console.WriteLine(userManagement.Test); //Just to see if it's still the same instance who holds for example the current user.
}
}
public interface IUser
{
string Name { get; }
void DoSomethingFancy();
}
public class User : IUser
{
public string Name { get; } = "default";
public void DoSomethingFancy()
{
}
}
public class UserAdv : IUser
{
public string Name { get; } = "Advanced";
public void DoSomethingFancy()
{
}
}
public interface IDatabase
{
void DoSomething();
}
public class Database : IDatabase
{
public void DoSomething()
{
}
}
public class UserManagement
{
public string Test;
public IUser User;
private IDatabase _Database;
public UserManagement(IUser user, IDatabase database)
{
User = user;
_Database = database;
Test = DateTime.Now.ToString();
}
}
如果我理解正确,我的主应用程序现在会初始化并配置Container
中的application startup
。 Bootstrapper
类在那里持有一个静态实例。 MyFramework
从静态UserManangement
实例中提取Container
的实例。
这是如何使用StructureMap
的正确方法吗?感谢您的耐心等待!
答案 0 :(得分:0)
您应该声明:
ForConcreteType<UserManagement>().Singleton();
修改强>
您可以在程序启动期间实现一个bootstrapper类并调用Initialize()
方法:
public sealed class Bootstrapper
{
private static StructureMap.Container _container;
public StructureMap.Container MyContainer
{
get { return _container; }
}
static Bootstrapper()
{
}
public static Initialize()
{
StructureMap.Configuration.DSL.Registry registry = new StructureMap.Configuration.DSL.Registry();
registry.For<IUser>().Use<User>();
registry.For<IDatabase>().Use<Database>();
registry.ForConcreteType<UserManagement>().Singleton();
_container = new Container(registry);
}
}
从UserManagement
类中删除容器初始化,让DI框架注入具体的类型/对象。
public class UserManagement
{
public string Test;
private IUser _user;
private IDatabase _database;
public UserManagement(IUser user, IDatabase database)
{
_user = user;
_database = database;
Test = DateTime.Now.ToString();
}
}
修改WPF测试窗口:
public partial class MainWindow : Window
{
static MainWindow()
{
// only for demonstration!!!
Bootstrapper.Initialize();
}
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Container container = Bootstrapper.MyContainer;
UserManagement instance = container.GetInstance<UserManagement>();
MessageBox.Show(instance.Test);
}
}