Reputation: 2355
I'm currently using Castle Windsor v2.5.1 and running into a few issues. I have a list where users select an item of their choice and begin working on the item selected. When an item is selected I inject the built item in my editor view model and display it to the end user. I've set all of my dependencies to have a transient lifestyle, which is causing me to deal with getting singleton dependencies injected, leaving me with stale data from a previously loaded item instead of a new object.
Here is what my view model constructor looks like:
public TabViewModel(
IRepository repository
IEditorViewModelFactory editorViewModelFactory)
{
Only one instance of this class is ever created within the lifetime of this application which is fine. But since users can (and do) select many different items throughout the lifetime of the application I end up using the same dependencies. Everytime a new item is selected inside the TabViewModel
view I call editorViewModelFactory.Create(the id of the item selected)
. Since only one instance of IEditorViewModelFactory
is created it makes sense that Windsor isn't injection fresh dependencies.
How do I force Windsor to inject a fresh set of dependencies whenever a new item is loaded?
The application works as follows. When the application loads it opens up it opens the view associated to the TabViewModel
class and injects both of it's dependencies. Only one instance of TabViewModel
is ever created. Inside this TabViewModel
object I hook into the IsSelected
property from TreeViewItem
(all items are stored in a tree view. Once an item is selected the following event from TabViewModel
is fired. I get the item that was selected and load the appropriate editor from my injected IEditorViewModelFactory
.
private void OnItemSelected(object sender, PropertyChangedEventArgs e)
{
const string isSelected = "IsSelected";
var selectedItem = sender as ItemViewModelTiny;
if (e.PropertyName == isSelected && selectedItem.IsSelected)
{
_editorViewModelFactory.Create(selectedItem.Id);
}
}
Since only one TabViewModel
is ever created then it makes sense that only one IEditorViewModelFactory
is created. Thus, even though I keep calling Create()
when an item is selected it's using the same dependencies created from when the first item was loaded.
My factory looks as follows:
public class EditorViewModelFactory : IEditorViewModelFactory
{
private readonly IRepository _repository;
public EditorViewModelFactory(IRepository repository)
{
_repository = repository;
}
public LocateEditorViewModel Create(int itemId)
{
var fullItem = _repository.GetFullItem(itemId);
return new EditorViewModel(_repository, fullItem.MapTo<ItemViewModel>());
}
}
Hope this clarifies my question.
Every time an item is selected I use my reviewing service to determine the users eligibility. While determining the eligibility I retrieve all current reviews for the selected item. When an item is reviewed it gets processed by my review processor with the reviews gathered from determining the users eligibility. This means that by always having the same instance of the reviewing service all previously retrieved reviews from other items are lingering in the system. I was able to fix this problem by simply clearing my list of reviews when finding the users eligibility. This works because when the editor is loaded the first thing that happens is determine if the user is eligible.
Here are both of the interfaces I refer to:
public interface IReviewingService
{
ReviewEligibilityResult GetReviewEligibility(ItemViewModel itemViewModel);
void Save(UserReview userReview);
}
public interface IReviewProcessor
{
void Process(UserReview userReview, IList<ReviewDto> reviews);
}
Hope that makes sense.
Upvotes: 3
Views: 119
Reputation: 233317
There's only one instance of EditorViewModelFactory
in memory because it's configured as a Singleton. Thus, because it holds on to the IRepository
instance by the _repository
field, there's also only one of those instances in memory, no matter how its lifetime is configured.
However, the Create
method returns a new instance of EditorViewModel
every time, but the _repository
instance is still the same, and is being passed into the EditorViewModel
instance.
If you need a new instance of IRepository
every time you create an instance of EditorViewModel
you could use an Abstract Factory.
Upvotes: 3