I am getting "Cannot Resolve Symbol Error" for StructureMap
ObjectFactory.TryGetInstance
But ObjectFactory.GetInstance is okay.
StructureMap Version 3.
Assembly include is "Using StructureMap;"
I am using this in an MVC 5 project.
Missing any other includes?'
ObjectFactory.Container.TryGetInstance is even better
ObjectFactory.Container.Try/GetInstance() is now replaced by creating a Container instance and using the methods from it. ObjectFactory was an encapsulation of Container anyway, from what I read.
public object GetService(Type serviceType)
{
// Previous way
return serviceType.IsAbstract || serviceType.IsInterface ?
ObjectFactory.Container.TryGetInstance(serviceType) :
ObjectFactory.Container.GetInstance(serviceType);
// New way
Container container = new Container();
return serviceType.IsAbstract || serviceType.IsInterface ?
container.TryGetInstance(serviceType) :
container.GetInstance(serviceType);
}
Source:
https://groups.google.com/forum/#!topic/structuremap-users/S7nBib95zh0
ObjectFactory.Container.GetInstance resolved this.
As Vahid N.'s answer may be useful in discussion :
My version, produces a lazy loaded thread safe singleton, but your Initialize method is not thread safe. Try:
public static class StructureMapObjectFactory
{
private static readonly Lazy<Container> _containerBuilder = new Lazy<Container>(() => new Container(), LazyThreadSafetyMode.ExecutionAndPublication);
public static IContainer Container
{
get { return _containerBuilder.Value; }
}
public static void Initialize<T>() where T : Registry, new()
{
Container.Configure(x =>
{
x.AddRegistry<T>();
});
}
}
And how to use :
DbContext dataContext = StructureMapObjectFactory.Container.TryGetInstance<DbContext>();
Related
I was using Unity DI Container v5.8.4 on my .NET Core 2.1 project and I needed to register Mediator object and I was using the configuration suggested here.
Now I have updated to v5.9.4 and I have an error about RegisterType method arguments:
Cannot convert from 'Unity.Lifetime.LifetimeManager' to 'Unity.Injection.InjectionMember'
This is my actual code:
public static IUnityContainer RegisterMediator(this IUnityContainer container, LifetimeManager lifetimeManager)
{
return container.RegisterType<IMediator, Mediator>(lifetimeManager)
.RegisterInstance<ServiceFactory>(type =>
{
var enumerableType = type
.GetInterfaces()
.Concat(new[] { type })
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
return enumerableType != null
? container.ResolveAll(enumerableType.GetGenericArguments()[0])
: container.IsRegistered(type)
? container.Resolve(type)
: null;
});
}
What have I to do to update the registration code?
They have changed the signature of the RegisterType in this PR and it is now taking a ITypeLifetimeManager instead of a LifetimeManager.
The HierarchicalLifetimeManager is now implementing the ITypeLifetimeManager interface so you just need to update the lifetimeManager parameter in your RegisterMediator method:
public static IUnityContainer RegisterMediator(this IUnityContainer container,
ITypeLifetimeManager lifetimeManager)
{
return container.RegisterType<IMediator, Mediator>(lifetimeManager)
...
}
Structuremap experts,
I found this post on stackoverflow ...
Passing constructor arguments when using StructureMap
Someone suggested to use the StructureMap configuration with runtime value like this
For<IProductProvider>().Use<ProductProvider>.Ctor<string>("connectionString").Is(someValueAtRunTime);
But example is not adequate enough to understand its declaration and usage. I try to find on StructureMap site as well but not much help ...
In my situation, I want to pass on the dependency of concrete DbContext (IDbContext) to the constructor of the class with connection string dynamically created during run time within that class.
Finally I managed to make it working ...
Here how I did it ...
Hope it will help someone, and thanks to PHeiberg for answer me before and showing me right direction.
Interface Definition
public interface ICreditCard
{
string GetName();
}
public interface IAdditionalCreditCard : ICreditCard
{
}
public class AdditionalCreditCard : IAdditionalCreditCard
{
private readonly string _name;
public AdditionalCreditCard(string name)
{
_name = name;
}
public string GetName()
{
return _name;
}
}
Define function in Structure map config code
Func<string, IAdditionalCreditCard> additionalCreditCard = value =>
ObjectFactory.With("name").EqualTo(value).GetInstance<AdditionalCreditCard>();
Add following configuration in ObjectFactory.Configure
ObjectFactory.Configure(config =>
{
config.For<Func<string, IAdditionalCreditCard>>().Use(additionalCreditCard);
});
And in code ...
public class PaymentSystem
{
private readonly Func<string, IAdditionalCreditCard> _addtionalCreditCard;
private IAdditionalCreditCard _addCreditCard;
public PaymentSystem(Func<string, IAdditionalCreditCard> additionalCredit)
{
_addtionalCreditCard = additionalCredit;
}
public string AddtionalSystemType()
{
_addCreditCard = _addtionalCreditCard("American Express");
return _addCreditCard.GetName();
}
}
The code you are posting is supposed to go in the setup code for StructureMap, which can go in the Initialize/Configure method or a Registry. The setup code is normally executed only once in the application's life cycle. So if you know the connection string value when the application is stared and you configure StructureMap, you can put the code you posted in the initialization of StructureMap. If the value is not known until later on, you need some kind of factory approach.
A factory approach could be done like this (in your StructureMap configuration code):
Func<string, IDbContext> createContext = value => {
/* create context based on value */
};
ObjectFactory.Initialize(c => {
For<Func<string, IDbContext>>().Use(createContext);
// The rest of you configuration ...
});
You can now use the Func to create an instance of the context when you need it:
public class ProductProvider : IProductProvider
{
private readonly Func<string, IDbContext> _contextCreator;
public ProductProvider(Func<string, IDbContext> contextCreator)
{
_contextCreator = contextCreator;
}
public IEnumerable<Product> GetProducts(string someValue)
{
using(var context = contextCreator(someValue))
{
return SomeOperationOnThe(context);
}
}
}
I'm working on an ASP.NET MVC project that support external plugins, now, I'm moving from Unity to Autofac and I need to wrap the lifetime objects of Autofac so the plugins won't have to reference it, in Unity I could do something this.
public sealed class UnityScopeFactory : IDependencyScopeFactory
{
private HttpRequestScope _httpRequest;
private SingletonScope _singleton;
private TransientScope _transient;
public IDependencyScope HttpRequest()
{
return _httpRequest ?? (_httpRequest = new HttpRequestScope());
}
public IDependencyScope Singleton()
{
return _singleton ?? (_singleton = new SingletonScope());
}
public IDependencyScope Transient()
{
return _transient ?? (_transient = new TransientScope());
}
private class HttpRequestScope : IDependencyScope
{
public object CreateScope()
{
return new HttpPerRequestLifetimeManager();
}
}
private class SingletonScope : IDependencyScope
{
public object CreateScope()
{
return new ContainerControlledLifetimeManager();
}
}
private class TransientScope : IDependencyScope
{
public object CreateScope()
{
return new TransientLifetimeManager();
}
}
}
I made similar thing in Autofac but I'm not sure whether it's the correct way to do that, I looked into the RegistrationBuilder of Autofac which is (unfortunately) internal and I came up with this.
public class AutofacScopeFactory : IDependencyScopeFactory
{
private HttpRequestScope _httpRequest;
private SingletonScope _singleton;
private TransientScope _transient;
public IDependencyScope HttpRequest()
{
return _httpRequest ?? (_httpRequest = new HttpRequestScope());
}
public IDependencyScope Singleton()
{
return _singleton ?? (_singleton = new SingletonScope());
}
public IDependencyScope Transient()
{
return _transient ?? (_transient = new TransientScope());
}
private class HttpRequestScope : IDependencyScope
{
public object CreateScope()
{
return new CurrentScopeLifetime();
}
}
private class SingletonScope : IDependencyScope
{
public object CreateScope()
{
return new RootScopeLifetime();
}
}
private class TransientScope : IDependencyScope
{
public object CreateScope()
{
return new CurrentScopeLifetime();
}
}
}
Also, after I got this to work, how can I use pass it to the ContainerBuilder?
In Unity I could do something like this.
public sealed class UnityDependencyContainer : IDependencyContainer
{
private readonly IUnityContainer _container;
public UnityDependencyContainer()
{
_container = new UnityContainer()
}
public void Register<TContract, TImplementation>(IDependencyScope scope) where TImplementation : TContract
{
LifetimeManager manager = scope.CreateScope() as LifetimeManager;
if (manager != null)
{
_container.RegisterType<TContract, TImplementation>(manager);
}
}
}
How do I pass an instance of IComponentLifetime to the method chain? is it a dead end?
public class AutofacContainer : IDependencyContainer
{
private static readonly ContainerBuilder Builder;
static AutofacContainer()
{
Builder = new ContainerBuilder();
}
public void RegisterType<TContract, TImplementation>(IDependencyScope scope) where TImplementation : TContract
{
IComponentLifetime manager = scope.CreateScope() as IComponentLifetime;
if (manager != null)
{
Builder.RegisterType<TImplementation>().As<TContract>();
}
}
}
Autofac doesn't separate scopes quite the way you have it outlined, so you might be trying to fit a square peg in a round hole.
Autofac scopes are more hierarchical. Any lifetime scope can spawn a child transient scope. For example, you might see...
Container/root lifetime
HttpRequest scope
Small task-specific transient scope
You can "tag" a scope and register components to a specific named/tagged scope - that's how the HttpRequest scope works. It gets "tagged" with a special identifier.
When you resolve objects is when it determines which lifetime scope owns it. Resolving happens from the most-nested scope. In the above hierarchy, you resolve items from the small task-specific transient scope whether they're singletons, request scoped, or whatever. When the singleton gets resolved, it will search up the lifetime scope stack and automatically assign "ownership" of the object to the root lifetime scope. When a per-request item gets resolved, it searches up the stack for the lifetime scope with the special "HTTP request" identifier and assigns ownership there. Factory-scoped items are resolved in the current lifetime scope.
Note: That discussion is a gross oversimplification of how it works. There is documentation explaining the lifetime scope mechanism on the Autofac site.
Point being, I see some things in the above design that don't really "jive" with the way Autofac does stuff.
The DependencyScopeFactory can't create its own transient or HttpRequest scopes. There are specific lifetime management components that start and end the HttpRequest scope, so you'd need to use those; there is no 'global' transient scope, so you can't really just create one.
HttpRequest scope, assuming you're using MVC, would look more like...
public ILifetimeScope HttpRequestScope
{
get { return AutofacDependencyResolver.Current.RequestLifetime; }
}
There's no analog for a transient scope because usage on that is supposed to be inline:
using(var transientScope = parentScope.BeginLifetimeScope())
{
// Do stuff and resolve dependencies using the transient scope.
// The IDisposable pattern here is important so transient
// dependencies will be properly disposed at the end of the scope.
}
When you register components, you don't register them "into a lifetime scope." You actually register them into a component registry and part of the component registration includes the ownership information about the lifetime of the component once it's resolved.
var builder = new ContainerBuilder();
// This component is factory-scoped and will be "owned" by whatever
// lifetime scope resolves it. You can resolve multiple of these
// in a single scope:
builder.RegisterType<FirstComponent>().As<ISomeInterface>();
// This component is a singleton inside any given lifetime scope,
// but if you have a hierarchy of scopes, you'll get one in each
// level of the hierarchy.
builder.RegisterType<SecondComponent>().InstancePerLifetimeScope();
// This component will be a singleton inside a specifically named
// lifetime scope. If you try to resolve it in a scope without that
// name, it'll search up the scope stack until it finds the scope
// with the right name. If no matching scope is found - exception.
builder.RegisterType<ThirdComponent>().InstancePerMatchingLifetimeScope("scopename");
// This is a per-HTTP-request component. It's just like the
// above InstancePerMatchingLifetimeScope, but it has a special
// tag that the web integration knows about.
builder.RegisterType<FourthComponent>().InstancePerHttpRequest();
If you're trying to make a container/registration agnostic interface, it wouldn't need a "lifetime scope manager" - instead, you'd need to pass some parameters indicating the intended lifetime scope and do the appropriate registration syntax (above) based on the incoming parameters.
Again, I'd recommend you check out that documentation.
Also, if you're using Unity, Autofac does have an Enterprise Library Configurator package that allows you to configure Autofac in a Unity style (since that's how EntLib likes to do things). That might be something to check out.
If you don't need to use Unity syntax at all... I'd recommend just moving to do things the native Autofac way. Trying to make one container look and act like another is a pretty painful endeavor.
Assuming your plugins are in separate assemblies or whatever, you could easily take advantage of some of the nice assembly-scanning syntax along with Autofac modules and hook up your plugins that way.
Most of the examples I've found for Automapper use the static Mapper object for managing type mappings. For my project, I need to inject an IMapperEngine as part of object construction using StructureMap so that we can mock the mapper in unit tests so we can't use the static mapper. I also need to support configuring AutoMapper Profiles.
My question is how can I configure the StructureMap registry so that it can supply an instance of IMappingEngine when an instance of MyService is constructed.
Here is the Service constructor signature:
public MyService(IMappingEngine mapper, IMyRepository myRepository, ILogger logger)
And here is the StructureMap Registry
public class MyRegistry : StructureMap.Configuration.DSL.Registry
{
public MyRegistry()
{
For<IMyRepository>().Use<MyRepository>();
For<ILogger>().Use<Logger>();
//what to do for IMappingEngine?
}
}
And the profile I want to load
public class MyAutoMapperProfile : AutoMapper.Profile
{
protected override void Configure()
{
this.CreateMap<MyModel, MyDTO>();
}
}
The Mapper class has a static property Mapper.Engine. Use this to register the engine with the container:
For<IMappingEngine>().Use(() => Mapper.Engine);
If you need to load your profiles before injecting the engine I would insert that configuration code alongside the above snippet.
Update
Your custom registry would look like this
class MyRegistry : Registry
{
public MyRegistry()
{
For<IMyRepository>().Use<MyRepository>();
For<ILogger>().Use<Logger>();
Mapper.AddProfile(new AutoMapperProfile());
For<IMappingEngine>().Use(() => Mapper.Engine);
}
}
This code runs once in your bootstrapper and any dependency of type IMappingEngine will afterwards be served with the value of the static property Mapper.Engine which is configured using your custom AutoMapperProfile.
The static API will be removed in version 5.0. Use a
MapperConfiguration instance and store statically as needed. Use
CreateMapper to create a mapper instance.
in new version (4.2.0 >=) we should hold and pass IMapper through DI.
a simple Configure Service should be like this (ASP.NET Core)
services.AddSingleton<IMapper>(_ => new MapperConfiguration(cfg =>
{
cfg.CreateMap<Foo,Bar>();
})
.CreateMapper());
and our service layer (with the help of constructor injection) :
public class CrudService<TDocument> : ICrudService<TDocument>
{
private readonly IMapper _internalMapper;
private readonly IRepository<TDocument> _repository;
public CrudService(IRepository<TDocument> repository, IMapper mapper)
{
_internalMapper = mapper;
_repository = repository;
}
public virtual ServiceResult<string> Create<TModel>(TModel foo)
{
var bar = _internalMapper.Map<TDocument>(foo);
try
{
_repository.Create(bar);
}
catch (Exception ex)
{
return ServiceResult<string>.Exception(ex);
}
return ServiceResult<string>.Okay(entity.Id);
}
}
consider TDocument as Bar, and TModel as Foo
update :
AutoMapper 4.2.1 released – Static is back
After a bit of feedback and soul searching and honestly tired of
dealing with questions, some of the static API is restored in this
release. You can now (and in the future) use Mapper.Initialize and
Mapper.Map
I wrote a blog post that shows my AutoMapper with StructureMap setup. I have created specific registries for AutoMapper 3.1.0 (also works for 3.1.1) and 3.0.0 and 2.2.1.
http://www.martijnburgers.net/post/2013/12/20/My-AutoMapper-setup-for-StructureMap.aspx
Here's what I ended up with as I couldn't figure out how to set the configuration on Mapper.Engine and have it passed into For().Use.
public MyRegistry()
{
For<IMyRepository>().Use<MyRepository>();
For<ILogger>().Use<Logger>();
//type mapping
For<ConfigurationStore>()
.Singleton()
.Use(ctx =>
{
ITypeMapFactory factory = ctx.GetInstance<ITypeMapFactory>();
ConfigurationStore store
= new ConfigurationStore(factory, MapperRegistry.AllMappers());
IConfiguration cfg = store;
cfg.AddProfile<MyAutoMapperProfile>();
store.AssertConfigurationIsValid();
return store;
});
For<IConfigurationProvider>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<IConfiguration>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<IMappingEngine>().Singleton().Use<MappingEngine>();
For<ITypeMapFactory>().Use<TypeMapFactory>();
}
How do I use StructureMap with OpenRasta? Can I use it in place of the internal dependency resolver, or is it only possible to use it in conjunction with the built-in DI (i.e. for my own app's dependencies)?
Thanks
Structure map code is here
Build it then reference the library. Or you could git submodule it.
Then add the following code into your openrasta project
public class DependencyResolver : IDependencyResolverAccessor
{
public IDependencyResolver Resolver
{
get { return new StructureMapDependencyResolver(ConfigureContainer()); }
}
public static IContainer ConfigureContainer()
{
var container = new Container();
container.Configure(c => c.Scan(s =>
{
//normal SM registrations
}));
return container;
}
}
Hope it helps
p.s Structure Map isn't officially supported, you're probably better off with Castle/Ninject.