У меня есть приложение WPF, использующее Caliburn.Micro и AutoFac.
В Bootstrapper.Configure() я регистрирую свои Views и ViewModels как:
protected override void Configure()
{
var builder = new ContainerBuilder();
// register view models
builder.RegisterAssemblyTypes(AssemblySource.Instance.ToArray())
.Where(type => type.Name.EndsWith("ViewModel"))
.AsSelf()
.InstancePerDependency();
// register views
builder.RegisterAssemblyTypes(AssemblySource.Instance.ToArray())
.Where(type => type.Name.EndsWith("View"))
.AsSelf()
.InstancePerDependency();
builder.Register<IWindowManager>(c => new WindowManager()).InstancePerLifetimeScope();
_container = builder.Build();
}
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[]
{
typeof (MainViewModel).Assembly, // assembly that holds all the ViewModels
typeof (MainView).Assembly // assembly that holds all the Views
};
}
Это хорошо работает, представления и модели представления хорошо отображаются в соответствии с этим соглашением, например. при создании экземпляра RandomViewModel отображается RandomView.
Кроме того, у меня есть много моделей представления редактирования/списка, которые являются производными от универсальных базовых классов, где универсальные типы являются сущностями в моем решении.
Например, когда у меня есть сущности UserEntity, OrderEntity, AccountEntity и т. д., я бы создал классы:
//base classes
abstract class EditViewModelBase<T> : IEditViewModelBase where T: IEntity
abstract class ListViewModelBase<T> : IListViewModelBase where T: IEntity
//implementations
class UserEditViewModel : EditViewModelBase<UserEntity> {...}
class OrderEditViewModel : EditViewModelBase<OrderEntity> {...}
class AccountEditViewModel : EditViewModelBase<AccountEntity> {...}
...
class UserListViewModel : ListViewModelBase<UserEntity> {...}
class OrderListViewModel : ListViewModelBase<OrderEntity> {...}
class UserListViewModel : ListViewModelBase<UserEntity> {...}
...
Теперь я хочу создать ViewModelFactory для общего поиска моделей представления:
class ViewModelFactory
{
public IEditViewModelBase CreateEditViewModel<T>()
{
//this method should do :
// if typeof(T) == typeof(UserEntity) return new UserEditViewModel();
// if typeof(T) == typeof(OrderEntity) return new OrderEditViewModel();
// if typeof(T) == typeof(UserEntity) return new UserEditViewModel();
...
}
public IListViewModelBase CreateListViewModel<T>()
{
//this method should do :
// if typeof(T) == typeof(OrderEntity) return new OrderListViewModel();
...
}
}
Как мне решить эту проблему, чтобы мне не приходилось менять ViewModelFactory каждый раз, когда я добавляю новые Entity и ViewModels в свое решение? Я думал о том, чтобы зациклиться на контейнере, используя приемы отражения, такие как IsInstanceOf и Activator.CreateInstance, но я не могу заставить его работать...