How do I put two instances of the same class or interface into MEF? How would I retrieve them?
By default, any part registered with MEF uses a singleton strategy for lifetime management (one per container). This is specified with the default CreationPolicy of Shared. I think you need to be clear on exactly what you need...
Are you wanting a new instance each time you compose?
If so, you can add a PartCreationPolicyAttribute to your export:
[PartCreationPolicy(CreationPolicy.NonShared), Export(typeof(IFoo))]
public class Foo : IFoo { }
Any time you compose a class using your container, you'll get a new instance of Foo.
Are you wanting two independent instances at the same time?
You'll probably want to think of an alternative pattern for getting instances of your parts. You could use an ExportFactory which would allow you to create new instances when you need it, e.g:
[Import]
public ExportFactory<IFoo> Factory { get; set; }
With:
public IFoo CreateFoo()
{
return Factory.CreateExport().Value;
}
(To use ExportFactory<T> with non-Silverlight applications, you should download it here - ExportFactory<T> never made it into .NET 4, only Silverlight).
Related
I have a class called GatewayClaims and a class called GatewayItems. And yes, the project I'm working on is a gateway.
I have several classes derived from GatewayItems: GatewayUser, GatewayCompany, GatewayRole and a few more. Each of these derived classes will hold claims. (Actually, just values. Simplified here.) And these claims gets passed forward to another service as a JWT token. This should work just fine.
But the problem is this:
public class GatewayClaim
{
public GatewayItem Item { get; set; } = new();
}
public abstract class GatewayItem
{
public List<GatewayClaim> Claims { get; set; } = new();
}
The "abstract" is part of the challenge here...
The problem is that I want separate tables for each item/claim pair so I have UserItems/UserClaims, CompanyItems/CompanyClaims, etc. So, preferably I would make the Claims type a generic class GatewayClaim<T> where T:GatewayItem, new() but then List<GatewayClaim> becomes invalid. And I don't weant to create a lot of derived classes just to support the various configurations that would be possible. I could use List<GatewayClaimValue<GatewayItem>> in GatewayItem which seems to work. But then I need to configure the DBSet and IEntityTypeConfiguration class for the various Claims tables and things become really messy by then.
So, I'm looking for an elegant solution to keep the amount of code to a minimum. And keep it readable!
To be clear: GatewayItem is NOT directly mapped to an entity, but a public class GatewayItemConfiguration<T> : IEntityTypeConfiguration<T> where T : GatewayItem is used to allow inheritance of basic configuration for any derived classes. This has an public virtual void Configure(EntityTypeBuilder<T> builder) method that gets overridden in the child configuration classes. Again, I'm trying to stay DRY in my code.
So the GatewayUser class uses a public class GatewayUserConfiguration : GatewayItemConfiguration<GatewayUser> {} class to configure the GatewayUser entity. I do the same way for a GatewayUserClaim which is derived from GatewayClaim at this moment. But the derived Claim types don't differ from their parent class, except the Items list is of a different type. Which is why I want to use GatewayClient<T> instead of GatewayClient.
I have several classes derived from GatewayItems: GatewayUser, GatewayCompany, GatewayRole
These are not closely-enough related to use inheritance in the database. If you want to have a common base class in code, simply don't map GatewayItem to an EF entity.
I want separate tables for each item/claim pair so I have UserItems/UserClaims
Great. Just introduce a UserClaim type, again perhaps inheriting from an unmapped Claim type, and it will map to a separate UserClaim table.
I am playing around building some buildingblocks based on database tables.
So I've created an UsersManager and a ValidationManager both based on the EDMX "templates".
I'd really like to loose couple those two components with MEF. But therefore i need to create Interfaces of the entityobjects exposed in the ValidationManager.
Is there an easy way of creating those Interfaces, in that manner i can still use the EDMX generated classes?
Thanx,
Paul
Using an example of a database with a Product Table, is this what you're trying to achieve....
but still use generated entity classes (using either the standard EF generator or another POCO generator of some sort).
I'm not sure - as you mention MEF and I don't see it being directly related.
The generated entity classes are partial classes which will allow you to extend the generated class which in this case you want to extend to implement an interface.
Presuming the following interface is going to be used to introduce the layer of abstraction...
public interface IEntity {
public bool IsDeleted { get; set; }
}
Create a new class file with and extended Product class...
public partial class Product : IEntity {
public bool IsDeleted {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
}
You have now extended your generated entity Product with the partial class custom code - and you can use it as normal through EF.
Now instead of your UserManager and ValidationManager classes having a hard reference to Product, instead they'll only have reference to IEntity.
If I didn't understand the question, please provide more details on exactly it is you want to do.
Is it possible to have Code First data classes declared with internal access as shown:
internal class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
I have a requirement that classes and its properties should not be visible outside of the assembly.
As long as your DbContext derived class that exposes your class to EF is in the same assembly, you should be able to. I don't happen to design my apps that way as I prefer more separation. But the context should be able to build the model and it should be able to interact with the classes (e.g. execute queries, save changes etc) if they are in the same assembly since it will have access to the internal class. Even with the various odd things we tried and wrote about in the Code First book, I never happened to try this particular scenario.
I have MVVM Project and I want to share one object( singleton ) from the model between several viewmodel what is the good practice to do that?
Thank you for the help
If the object is needed and does not provide value without it force the interface within the object via Constructor Injection; do not push a concrete type via injection always make use of an interface.
Since you are not making use of an IoC container such as Unity, you will need to create your singleton instance at the startup of your application and then make sure that the given instance is passed in via the given ViewModels constructor as needed.
A better approach would be pushing the singleton instance to a service which can provide the needed behavior and then disregard pushing the singleton into the Model. This would be a more MVVM purist approach and will separate concerns across your Models/ViewModels.
EDIT:
If you were making use of Unity you would define a Lifetime Manager at the time of registration.
// Register a type to have a singleton lifetime without mapping the type
// Uses the container only to implement singleton behavior
myContainer.RegisterType<MySingletonObject>(new ContainerControlledLifetimeManager());
// Following code will return a singleton instance of MySingletonObject
// Container will take over lifetime management of the object
myContainer.Resolve<MySingletonObject>();
Once you do this any attempt to resolve MySingletonObject via the IUnityContainer would resolve to the same instance providing the singleton behavior you so desire across the application. ViewModels themselves should not need to have the same instance returned. The data it needs should be abstracted away via a service as referenced earlier which could potentially behave like a singleton and provide a stateful implementation if needed but the ViewModel should not need to be a singleton. If you find yourself making either a Model or ViewModel a singleton; take a step back and analyze your design.
If you have control over all viewmodels then an easy approach (that I've used personally) is to just put a static variable on the base class of all viewmodels and make that accessible to all inheritors (either protected or even public if its useful outside of the viewmodels).
It's good practice anyway to have a common base class for your viewmodels since it allows you to implement property notification in one place (and other common functionality, like messaging etc.) instead of replicating it in all viewmodels.
Something like this is what I've used in my projects:
public class MyViewModelBase : INotifyPropertyChanged
{
private static MySharedSingleton _sharedObj;
static MyViewModelBase()
{
_sharedObj = new MySharedSingleton(/* initialize it here if needed */);
}
// or public
protected MySharedSingleton SharedObject { get { return _sharedObj; } }
// INotifyPropertyChanged stuff
// ...
}
public class SomeViewModel : MyViewModelBase
{
void SomeMethod()
{
SharedObject.DoStuff();
}
}
If the construction of the shared singleton object is heavy, you can of course use any of the standard techniques for lazy instantiation of it.
I would suggest that you inject the dependency into each view model (either constructor or property injection for example), and always work against abstractions in your view models, so that your dependency can easily be mocked or replaced as required. You then just need to ensure that each view model uses the same instance of your type - if you are using an IoC container, you can register a shared instance of your type easily.
I use a separate class for my global singleton with a model. This relieves me of agonizing over how to inject this model into view models and other models. E.g.
The singleton:
public class ApplicationModel
{
public string LoggedOnUser { get; set; }
// Etc.
private ApplicationModel() {
// Set things up.
}
private static ApplicationModel _active;
public static ApplicationModel Current {
get {
if (_active == null) {
_active = new ApplicationModel();
}
return _active;
}
}
}
The view model that needs to hold no reference to the singleton:
public class SomeViewModel
{
private string _user;
public SomeViewModel() {
_user = ApplicationModel.Current.LoggedOnUser;
}
}
I have a large 'Manager' class which I think is doing too much but I am unsure on how to divide it into more logical units.
Generally speaking the class basically consists of the following methods:
class FooBarManager
{
GetFooEntities();
AddFooEntity(..);
UpdateFooEntity(..);
SubmitFooEntity(..);
GetFooTypes();
GetBarEntities();
}
The Manager class is part of my business logic and constains an instance of another "Manager" class on the data access level which contains all CRUD operations for all entities.
I have different entities coming from the data access layer and therefore have a converter in place outside of the Manager class to convert data entities to business entities.
The reason for the manager classes was that I wanted to be able to mock out each of the "Manager" classes when I do unittesting. Each of the manager classes is now over 1000 loc and contain 40-50 methods each. I consider them to be quite bloated and find it awkward to put all of the data access logic into a single class. What should I be doing differently?
How would I go about splitting them and is there any specific design-pattern should I be using?
You really shouldn't put all data access into one class unless it's generic. I would start by splitting out your data access classes into one manager per object or related groups of objects, i.e. CompanyManager, CustomerManager, etc. If your need to access the manager through one "god class" you could have an instance of each manager available in your one true Manager class.
Your FooBarManager looks a lot like a God Object anti pattern.
In a situation like yours, consider delving into Patterns of Enterprise Application Architecture, by Martin Fowler. At first sight, it looks like you want to create a Data Mapper. But consider alternatives like Active Records, that might be enough for your needs.
Also consider using an ORM library/software for your platform. Building your own without a good reason will only confront you to the many problems that have already been more or less solved by these tools.
/ FooManager
Manager (derive from Manager)
\ BarManager
Should be self-explaining
I'd suggest using composition. Think about the functions the manager is doing. Split them along the lines of single responsibility. It appears most of FooBarManager is a collection of Foo and bar entities. So, at a minimum, break out the collection logic from FooBarManager
public class EntityCollection<T> : IList<T>
where T : BaseEntity
{ /* all management logic here */}
public class FooCollection : EntityCollection<foo> {}
public class BarCollection : EntityCollection<bar> {}
public class FooBarManager
{
public FooCollection { /*...*/ }
public BarCollection { /*...*/ }
public FooBarManager() : this(new FooCollection(), new BarCollection()){}
public FooBarManager(FooCollection fc, BarCollection bc) { /*...*/ }
}