How to retrieve/import object using MEF in Prism - c#

I have a requirement to have one object (RuleFile), representing file to be serialized, across the whole application like word (*.docs) file that will be associated with my application.
I am using Prism 5 along with MEF as a dependency injection container.
[Export]
[Serializable()]
public class RuleFile : NotificationBase, IRuleFile { }
Now i have decorated the object with [Export] and trying to import it in one of the MyViewModel but it is giving null.
public class MyViewModel : ViewModelBase
{
[Import]
private RuleFile RuleFile; // 'null' coming here
}
Kindly direct me what am i missing? Or tell me any other way to best handle this scenario.

Are you checking the value in the constructor? Imports that are decorated directly on the property are resolved after the constructor. If you want to access the RuleFile in the constructor you'd need to set it up like this
public class MyViewModel : ViewModelBase
{
public RuleFile RuleFile { get; set; }
[ImportingConstructor]
public MyViewModel(RuleFile ruleFile)
{
RuleFile = ruleFile;
}
}
Alternatively, you can implement the IPartImportsSatisfiedNotification which will give you a notification method to signify that the imports have been resolved. Like this
public class MyViewModel : ViewModelBase, IPartImportsSatisfiedNotification
{
[Import]
public RuleFile RuleFile { get; set; }
public void OnImportsSatisfied()
{
// Signifies that Imports have been resolved
}
}

Related

What is difference between assign ExpandableObjectConverter attribute to Property level or class level?

Assuming WinForms UserControl class. and there's another property of object ( class Car )
[TypeConverter(typeof(ExpandableObjectConverter))] // first approach - class level
public class Car
{
public int Model{get;set;}
public string Name{get;set;}
}
public class UserControl1: UserControl
{
[TypeConverter(typeof(ExpandableObjectConverter))] // Second approach - property level
public Car CarProperty{
get;
}
}
What is difference between class level and property level when insert this attribute specially? I see some .NET Libraries for example DevExpress doing it in property level.
[TypeConverter(typeof(ExpandableObjectConverter)), DXCategory(CategoryName.Behavior)]
public LayoutViewField LayoutViewField {
get { return layoutViewFieldCore; }
set { AssignLayoutViewField(value); }
}
and .NET standard doing
[TypeConverter(typeof(FontConverter))]
public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDisposable
I missed up now what is difference? And which one should we end up..

c# class inherits from base class with constructor with dependency injection

I have a project using Dependency Injection (Ninject) where I have the following class:
public class SecurityService : BaseService
{
ISecurityRepository _securityRepo = null;
public SecurityService(ISecurityRepository securityRepo)
{
_securityRepo = securityRepo;
}
}
Because BaseService is going to be referenced in many other service classes I wanted to add there a method that also go to Data Repository and get some information so I don't have to repeat the same code along the other service classes.
Here is what I have for BaseRepository:
public partial class BaseService
{
IEntityRepository _entityRepo = null;
public BaseService(IEntityRepository entityRepo)
{
_entityRepo = entityRepo;
}
public Settings AppSettings
{
get
{
return _entityRepo.GetEntitySettings();
}
}
}
But when I compile I get the following error:
There is no argument given that corresponds to the required formal parameter 'entityRepo' of 'BaseService.BaseService(IEntityRepository)'
And the error make sense because now I have a constructor that I guess is expecting something.
Any clue how to fix this but that I can still have my dependency injection in BaseRepository class?
UPDATE
I just tried to remove the constructor and use the attribute [Inject] but when debugging I see that _entityRepo is NULL.
Add the dependency to the constructor for the derived class, and pass it along.
public SecurityService(ISecurityRepository securityRepo, IEntityRepository entityRepo)
: base(entityRepo)
{
_securityRepo = securityRepo;
}
I could make it work:
I just convert the private property to be public and then [Inject] attribute started to work.
public partial class BaseService
{
[Inject]
public IEntityRepository EntityRepo { get; set; }
}
Pass the Repository object to the base class via the child class constructor:
public SecurityService(ISecurityRepository securityRepo) : base(IEntityRepository)
{
//Initialize stuff for the child class
}

Public property of private class

I have a NavigationModel class which implements site navigation. Internally there is a private implementation of NavigationNode which I want to be able to declare within the NavigationModel but not outside of it. How would I accomplish this? When I do the following:
public class NavigationModel
{
public List<NavigationNode> NavigationNodes { get; set; }
public NavigationModel()
{
}
private class NavigationNode
{
}
}
The property tells me:
Inconsistent accessibility: property type
'List' is less accessible than
property 'NavigationModel.NavigationNodes'
The error is raised because by declaring NavigationModel as public, you create a public interface that is used to access NavigationModel. Part of this interface are the signatures of the public methods or properties. By that, you'd publish class NavigationNode that is supposed to be private - hence the error.
In order to fix this, you could create a public interface that only contains the parts of NavigationNode that you want to publish. If you do not want to publish anything, the interface is empty. The following sample shows the basic components:
Public interface INavigationNode.
Property of type List<INavigationNode>.
Private class NavigationNode that implements the interface.
public interface INavigationNode
{
// Add parts of NavigationNode that you want to publish
}
public class NavigationModel
{
public List<INavigationNode> NavigationNodes { get; set; }
public NavigationModel()
{
}
private class NavigationNode : INavigationNode
{
}
}
NavigationNode needs to be public for this to work properly. Making it public still keeps the declaration internal to the containing class NavigationModel yet classes outside NavigationModel can reference it.

Making Microsoft Unity dependency properties available in constructors

I've got the following bit of (simplified) code:
public abstract class BaseClass
{
[Dependency]
public IRequiredService RequiredService { get; set; }
protected string RequiredParameter { get; private set; }
public BaseClass(string requiredParameter)
{
this.RequiredParameter = requiredParameter;
}
}
public class DerivedClass : BaseClass
{
public DerivedClass(string requiredParameter) : base(requiredParameter)
{
RequiredService.DoSomething(); //this will fail!
}
}
In other words, I'd like to have access to the Unity-filled RequiredService in the constructor... but that's impossible, since that property hasn't been filled by Unity yet. I COULD add the IRequiredService as a required constructor parameter, but then I'd need to refactor every constructor of every derived class to also include that parameter.
I was wondering if there's a better way.
In short, I'd like to run a bit of code after a class has been constructed and after unity has filled all the class' properties marked with the [Dependency] attribute.
Is there a simple way to do this?
Instead of putting RequiredService.DoSomething(); in the constructor you can put it in a inside a [InjectionMethod] call, this will allow you to reliably know that RequiredService has been populated.

Why set up a constructor in a class to set a base parameter when I could do the same in a class it inherits from?

I have the following code:
public abstract class ApiBaseController : ApiController
{
protected IUow Uow { get; set; }
}
and:
public class ContentStatusController : ApiBaseController
{
public ContentStatusController(IUow uow)
{
Uow = uow;
}
}
Is there any reason why I could not code the assignment of Uow (using IOC) in the ApiBaseController?
The reason I ask is because I am trying to do something similar to the Code Camper application sample and I notice that in that sample the Unit of work is assignment is always performed in the constuctors of the controllers themselves rather than in the ApiBaseConstructor. In the examples I see this is the only thing that's done in the constructors.
If I did the assignement in the base controller then how could I code that and would Uow still need to have "protected" for it to be available in controllers that inherit from the ApiBaseController?
Your IOC container is injecting dependencies via constructors. If you want to continue to use that mechanism (some containers allow e.g. property injection, but not everyone likes to do that) then you'll still need to have the same constructor in your derived class to pass the injected component down to the base class1.
Something like:
public abstract class ApiBaseController : ApiController
{
public ApiBaseController(IUow uow)
{
Uow = uow;
}
protected IUow Uow { get; private set; }
}
public class ContentStatusController : ApiBaseController
{
public ContentStatusController(IUow uow) : base(uow) //<-- This is needed
{
}
}
1Because classes don't inherit constructors.

Categories

Resources