我想知道注册容器本身是否有任何副作用
IContainer container;
ContainerBuilder builder = new ContainerBuilder();
container = builder.Build();
builder.RegisterInstance(container).As<IContainer>();
并像这样使用它
builder.RegisterType<IManagmentServiceImp>().As<ManagmentServiceImp>()
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IContainer) && pi.Name == "Container",
(pi, ctx) => container
));
或者它是否会起作用。
答案 0 :(得分:24)
您的代码不安全,因为您在初始化之前注册了一个实例。
如果您需要访问组件内的容器(这不是一个好主意),您可以依赖具有import ftplib
import socket
import ssl
class FTP(ftplib.FTP):
def getline(self):
line = self.file.readline(self.maxline + 1).decode("utf-8")
if len(line) > self.maxline:
raise ftplib.Error("got more than %d bytes" % self.maxline)
if self.debugging > 1:
print('*get*', self.sanitize(line))
if not line:
raise EOFError
if line[-2:] == ftplib.CRLF:
line = line[:-2]
elif line[-1:] in ftplib.CRLF:
line = line[:-1]
return line
class FTPS(ftplib.FTP_TLS):
def __init__(self, host='', user='', passwd='', acct='', keyfile=None, certfile=None, timeout=60):
ftplib.FTP_TLS.__init__(self, host=host, user=user, passwd=passwd, acct=acct, keyfile=keyfile,
certfile=certfile, timeout=timeout)
def connect(self, host='', port=0, timeout=-999, source_address=None):
if host != '':
self.host = host
if port > 0:
self.port = port
if timeout != -999:
self.timeout = timeout
try:
self.sock = socket.create_connection((self.host, self.port), self.timeout)
self.af = self.sock.family
self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, ssl_version=ssl.PROTOCOL_TLSv1_2)
self.file = self.sock.makefile('rb')
self.welcome = self.getresp()
except Exception as e:
print(e)
return self.welcome
if __name__ == "__main__":
ftps = FTPS()
ftps.connect("host", 990) # Returns b'welcomemessage'
ftps.login("user", "pwd")
ftps.prot_p()
ftps.close()
方法的ILifetimeScope
。
Resolve
public class ManagmentServiceImp
{
public ManagmentServiceImp(ILifetimeScope scope)
{
}
}
会自动在 Autofac 中注册,您无需为其添加注册。
有关详细信息,请参阅 Autofac 文档中的Controlling Scope and Lifetime。
顺便说一句,依赖IoC容器并不是一个好习惯。看起来你使用Service Locator反模式。如果您需要容器延迟加载依赖项,则可以将合成与ILifetimeScope
或Func<T>
Lazy<T>
在这种情况下,首次访问时会创建public class ManagmentServiceImp
{
public ManagmentServiceImp(Lazy<MyService> myService)
{
this._myService = myService;
}
private readonly Lazy<MyService> _myService;
}
。
有关详细信息,请参阅 Autofac 文档中的Implicit Relationship。
答案 1 :(得分:10)
您可以使用此扩展方法:
public static void RegisterSelf(this ContainerBuilder builder)
{
IContainer container = null;
builder.Register(c => container).AsSelf();
builder.RegisterBuildCallback(c => container = c);
}
像这样使用它:builder.RegisterSelf();
答案 2 :(得分:2)
由于您需要向builder.RegisterInstance()
提供容器的实例,因此您需要在将其作为参数传递之前对其进行初始化,而您当前没有这样做。但是,如果构建容器构建器以构建AFTER注册(和容器初始化),则可以成功解析类中的容器实例。
请注意,这肯定是依赖注入中的设计气味,你绝对不应该这样做。您的容器/内核应该只存在于对象图的顶层。如果你开始注入你的容器,你几乎肯定会去服务定位器反模式。
void Main()
{
IContainer container = new ContainerBuilder().Build();
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterInstance(container).As<IContainer>();
builder.RegisterType<ManagementServiceImp>().As<IManagmentServiceImp>()
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IContainer) && pi.Name == "Container",
(pi, ctx) => container
));
container = builder.Build();
var instance = container.Resolve<IManagmentServiceImp>();
}
public class ManagementServiceImp : IManagmentServiceImp
{
private IContainer _container;
public ManagementServiceImp(IContainer Container)
{
_container = Container;
_container.Dump();
}
}
public interface IManagmentServiceImp { }
答案 3 :(得分:-2)
虽然我没有回答你的问题。尝试在服务类中获取容器的句柄或者除了相当于IModule之外的任何东西都是代码味道。
您的服务代码不应该了解IOC IMO。